home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-2.iso / os2 / gnucal.zip / gcal.c < prev    next >
C/C++ Source or Header  |  1995-12-20  |  137KB  |  4,168 lines

  1. /*
  2. *  gcal.c:  Main part which controls the extended calendar program
  3. *
  4. *
  5. *  Copyright (C) 1994, 1995 Thomas Esken
  6. *
  7. *  This software doesn't claim completeness, correctness or usability.
  8. *  On principle I will not be liable for any damages or losses (implicit
  9. *  or explicit), which result from using or handling my software.
  10. *  If you use this software, you agree without any exception to this
  11. *  agreement, which binds you LEGALLY !!
  12. *
  13. *  This program is free software; you can redistribute it and/or modify
  14. *  it under the terms of the `GNU General Public License' as published by
  15. *  the `Free Software Foundation'; either version 2, or (at your option)
  16. *  any later version.
  17. *
  18. *  You should have received a copy of the `GNU General Public License'
  19. *  along with this program; if not, write to the:
  20. *    Free Software Foundation
  21. *    59 Temple Place, Suite 330
  22. *    Boston, MA 02111-1307  USA
  23. */
  24.  
  25.  
  26.  
  27. static char rcsid[]="$Id: gcal.c 0.39 1995/12/20 00:03:09 tom Exp $";
  28.  
  29.  
  30.  
  31. /*
  32. *  Include header files
  33. */
  34. #include "gcal_tai.h"
  35. #if HAVE_ASSERT_H
  36. #  include <assert.h>
  37. #endif
  38. #if HAVE_CTYPE_H
  39. #  include <ctype.h>
  40. #endif
  41. #if HAVE_UNISTD_H
  42. #  include <unistd.h>
  43. #endif
  44. #ifdef GCAL_EPAGER
  45. #  if HAVE_SIGNAL_H
  46. #    include <signal.h>
  47. #  endif
  48. #  if HAVE_FCNTL_H
  49. #    include <fcntl.h>
  50. #    if !HAVE_DUP
  51. #      define dup(old)            (fcntl(old, F_DUPFD, 0))
  52. #    endif
  53. #    if !HAVE_DUP2
  54. #      define dup2(old, new)      (close(new), fcntl(old, F_DUPFD, new))
  55. #    endif
  56. #  endif
  57. #  if HAVE_SYS_WAIT_H
  58. #    include <sys/wait.h>
  59. #  endif
  60. #  ifndef WEXITSTATUS
  61. #    define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
  62. #  endif
  63. #  ifndef WIFEXITED
  64. #    define WIFEXITED(stat_val)   (((stat_val) & 0xff) == 0)
  65. #  endif
  66. #endif /* GCAL_EPAGER */
  67. #include "gcal.h"
  68.  
  69.  
  70.  
  71. /*
  72. *  Set borland/turbo-c specific MSDOS stack length in case USE_RC is defined  ;<
  73. */
  74. #if USE_RC
  75. #  if defined(MSDOS) && defined(__TURBOC__)
  76. #    include <dos.h>
  77. PUBLIC Uint _stklen=0x2000;
  78. #  endif
  79. #endif
  80.  
  81.  
  82.  
  83. /*
  84. *  Function prototypes
  85. */
  86. #if __cplusplus
  87. extern "C"
  88. {
  89. #endif
  90. /*
  91. ************************************************** Defined in `gcal_fil.c'
  92. */
  93. IMPORT FILE *
  94. file_open __P_((      char       *filename,
  95.                 const Fmode_enum  mode));
  96. IMPORT void
  97. insert_response_file __P_((      char *filename,
  98.                            const char *opt_list,
  99.                                  int  *my_argc_max,
  100.                                  int  *my_argc,
  101.                                  char *my_argv[]));
  102. IMPORT void
  103. write_log_file __P_((const char       *filename,
  104.                      const Fmode_enum  mode,
  105.                      const char       *mode_msg,
  106.                      const int         argc,
  107.                            char       *argv[]));
  108. /*
  109. ************************************************** Defined in `gcal_hdy.c'
  110. */
  111. IMPORT int
  112. eval_holiday __P_((      int  day,
  113.                    const int  month,
  114.                    const int  year,
  115.                    const int  wd,
  116.                    const Bool forwards));
  117. IMPORT void
  118. print_all_holidays __P_((      Bool init_data,
  119.                          const Bool detect));
  120. /*
  121. ************************************************** Defined in `gcal_prt.c'
  122. */
  123. IMPORT void
  124. print_calendar __P_((void));
  125. #if USE_RC
  126. /*
  127. ************************************************** Defined in `gcal_rc.c'
  128. */
  129. IMPORT void
  130. rc_clean_flags __P_((void));
  131. IMPORT char *
  132. rc_get_date __P_((      char *ptr_char,
  133.                         Bool *is_weekday_mode,
  134.                         int  *d,
  135.                         int  *m,
  136.                         int  *y,
  137.                         int  *n,
  138.                         int  *len,
  139.                         char *hc,
  140.                         int  *hn,
  141.                         int  *hwd,
  142.                   const char *filename,
  143.                   const int   line,
  144.                   const char *line_buffer,
  145.                   const Bool  on_error_exit));
  146. IMPORT Bool
  147. set_dvar __P_((const char      *line_buffer,
  148.                const char      *filename,
  149.                const int        line,
  150.                const Dvar_enum  mode));
  151. /*
  152. ************************************************** Defined in `gcal_rcu.c'
  153. */
  154. IMPORT void
  155. rc_use __P_((void));
  156. #endif /* USE_RC */
  157. /*
  158. ************************************************** Defined in `gcal_tty.c'
  159. */
  160. IMPORT void
  161. print_text __P_((      FILE       *fp,
  162.                        char       *txt_line,
  163.                  const Dmode_enum  mode));
  164. #if USE_PAGER
  165. IMPORT void
  166. get_tty_scr_size __P_((int *rows,
  167.                        int *cols));
  168. #endif
  169. IMPORT void
  170. get_tty_hls __P_((const char *sequence_str));
  171. /*
  172. ************************************************** Defined in `gcal_utl.c'
  173. */
  174. IMPORT void
  175. my_extended_help __P_((      FILE *fp,
  176.                        const int   longopt_symbolic));
  177. IMPORT void
  178. my_basic_help __P_((FILE *fp));
  179. IMPORT void
  180. my_license __P_((      FILE *fp,
  181.                  const char *prgr_id));
  182. IMPORT void
  183. my_version __P_((      FILE *fp,
  184.                  const char *prgr_id));
  185. IMPORT VOID_PTR
  186. my_malloc __P_((const int   amount,
  187.                 const int   exit_status,
  188.                 const char *module_name,
  189.                 const int   module_line,
  190.                 const char *var_name,
  191.                 const int   var_contents));
  192. IMPORT VOID_PTR
  193. my_realloc __P_((      VOID_PTR  ptr_memblock,
  194.                  const int       amount,
  195.                  const int       exit_status,
  196.                  const char     *module_name,
  197.                  const int       module_line,
  198.                  const char     *var_name,
  199.                  const int       var_contents));
  200. IMPORT void
  201. my_error __P_((const int   exit_status,
  202.                const char *module_name,
  203.                const int   module_line,
  204.                const char *var_name,
  205.                const int   var_contents));
  206. IMPORT int
  207. my_atoi __P_((const char *s));
  208. IMPORT Bool
  209. get_actual_date __P_((void));
  210. IMPORT int
  211. compare_d_m_name __P_((const char       *s,
  212.                        const Cmode_enum  mode));
  213. IMPORT int
  214. weekday_of_date __P_((const int day,
  215.                       const int month,
  216.                       const int year));
  217. IMPORT int
  218. day_of_year __P_((const int day,
  219.                   const int month,
  220.                   const int year));
  221. IMPORT int
  222. days_of_february __P_((const int year));
  223. IMPORT Bool
  224. valid_date __P_((const int day,
  225.                  const int month,
  226.                  const int year));
  227. IMPORT const char *
  228. usage_msg __P_((void));
  229. IMPORT void
  230. put_longopt_description __P_((FILE *fp));
  231. /*
  232. ************************************************** Defined in `gcal.c'
  233. */
  234. EXPORT int
  235. main __P_((int   argc,
  236.            char *argv[]));
  237. EXPORT int
  238. eval_longopt __P_((char *longopt,
  239.                    int  *longopt_symbolic));
  240. LOCAL void
  241. rearrange_argv __P_((const char *opt_list,
  242.                            int  *argc,
  243.                            char *argv[]));
  244. LOCAL void
  245. check_command_line __P_((int   argc,
  246.                          char *argv[]));
  247. LOCAL void
  248. build_month_list __P_((char *argv[]));
  249. LOCAL void
  250. eliminate_invalid_data __P_((void));
  251. #if __cplusplus
  252. }
  253. #endif
  254.  
  255.  
  256.  
  257. /*
  258. *  Declare public(extern) variables
  259. */
  260. #if USE_RC
  261. IMPORT Dvar_struct  rc_dvar[RC_DVAR_MAX];       /* Date variables a[=`mmdd']...z[] (`yyyy'@{a|b|...|z}[[-]<n>]) */
  262. IMPORT int          rc_period;                  /* Amount of period of fixed date warnings */
  263. IMPORT int          rc_elems;                   /* Amount of resource file entries */
  264. IMPORT int          rc_have_today_in_list;      /* [-c]d */
  265. IMPORT char        *rc_adate;                   /* Text of modified actual date %... */
  266. IMPORT char        *rc_filename;                /* Name of alternative resource file(s) -f|F<NAME[+...]> */
  267. IMPORT char        *rc_grp_sep;                 /* Fixed date list grouping separator [-c]g[txt] */
  268. IMPORT Bool         rc_julian_flag;             /* -jc */
  269. IMPORT Bool         rc_both_dates_flag;         /* -jcb */
  270. IMPORT Bool         rc_use_flag;                /* -c */
  271. IMPORT Bool         rc_all_dates_flag;          /* -C[] or -C[][T|W|M|Y] or -c[][T|W|M|Y] or -F<> */
  272. IMPORT Bool         rc_sort_des_flag;           /* [-c]- */
  273. IMPORT Bool         rc_enable_fn_flag;          /* [-c]a */
  274. IMPORT Bool         rc_enable_hda_flag;         /* [-c]e */
  275. IMPORT Bool         rc_enable_hdl_flag;         /* [-c]E */
  276. IMPORT Bool         rc_weekno_flag;             /* [-c]k */
  277. IMPORT Bool         rc_period_list;             /* [-c]l */
  278. IMPORT Bool         rc_omit_date_flag;          /* [-c]o */
  279. IMPORT Bool         rc_title_flag;              /* [-c]x */
  280. IMPORT Bool         rc_count_flag;              /* [-c]z */
  281. IMPORT Bool         rc_period_flag;             /* [-c]<<<<n>>[<d|w|+|-]>|`mmdd'|`mmww[w]'<n>> */
  282. IMPORT Bool         rc_tomorrow_flag;           /* [-c]t */
  283. IMPORT Bool         rc_week_flag;               /* [-c]w */
  284. IMPORT Bool         rc_month_flag;              /* [-c]m */
  285. IMPORT Bool         rc_year_flag;               /* [-c]y */
  286. IMPORT Bool         rc_week_year_flag;          /* [-c<<n>>]w */
  287. IMPORT Bool         rc_forwards_flag;           /* [-c<<n>|w|m|y>]+ */
  288. IMPORT Bool         rc_backwards_flag;          /* [-c<<n>|w|m|y>]- */
  289. IMPORT Bool         rc_nzero_ldvar_flag;        /* --hidden   don't reset local date variables */
  290. IMPORT Bool         is_date_given;              /* Is a date given in the command line? */
  291. #endif /* USE_RC */
  292.  
  293.  
  294.  
  295. /*
  296. *  Define public(extern) variables
  297. */
  298. PUBLIC const int  dvec[]=
  299.  {
  300.    31, 28, 31, 30, 31, 30,
  301.    31, 31, 30, 31, 30, 31
  302.  };                                             /* Number of days in months' */
  303. PUBLIC const int  mvec[]=
  304.  {
  305.      0,  31,  59,  90, 120, 151,
  306.    181, 212, 243, 273, 304, 334
  307.  };                                             /* Number of past days of month */
  308. /*
  309.    The long option table is a vector of `Lopt_struct' terminated by an element
  310.      containing a `long_name' which is zero!
  311.      all string entries in this structure must be entered in lower case letters
  312.      in ascending sort order and distinguishable in structure element `long_name'!
  313.      `symbolic_name': the symbolic name of the long option.
  314.      `long_name':     the full name of the long option.
  315.      `short_name':    a list of short options (maximum 5) terminated by NULL,
  316.                         which order corresponds to the order of field `largs'.
  317.      `larg_mode':     states whether an option requires arguments or not.
  318.                         LARG_NO or 0 means:
  319.                           option requires no argument, e.g. --foo
  320.                         LARG_NO_OR_ONE or 1 means:
  321.                           option may have an argument, e.g. --foo or --foo=BAR
  322.                         LARG_ONE or 2 means:
  323.                           option must have an argument, e.g. --foo=BAR
  324.                         if this field is set to ARG_NO_OR_ONE and NO argument
  325.                         trails the option, the `short_name[0]' contains
  326.                         the default value and is returned!
  327.      `largs':         a list of possible SPECIAL arguments (maximum 5) terminated
  328.                         by NULL, from which only one may be selected.
  329.                         if it's set to NULL only, any given argument is allowed,
  330.                         otherwise only one of the listed SPECIAL arguments.
  331.                         The SPECIAL arguments may be abbreviated in case this
  332.                         is done unambigously.
  333. */
  334. PUBLIC const Lopt_struct  lopt[]=
  335. {
  336. /*
  337.   { int symbolic_name, char *long_name, char *short_name[LARG_MAX], int larg_mode, char *largs[LARG_MAX]},
  338. */
  339. #if USE_RC
  340.   {
  341.     SYM_DATE_VARIABLE2,
  342.     "assign",
  343.     {"v", NULL},
  344.     LARG_ONE,
  345.     {NULL}
  346.   },
  347. #endif
  348.   {
  349.     SYM_BLOCKS,
  350.     "blocks",
  351.     {"b", NULL},
  352.     LARG_ONE,
  353.     {NULL}
  354.   },
  355.   {
  356.     SYM_CALENDAR_DATES,
  357.     "calendar-dates",
  358.     {"j", "jb", NULL},
  359.     LARG_ONE,
  360.     {"julian", "both", NULL}
  361.   },
  362.   {
  363.     SYM_LICENSE2,
  364.     "copyleft",
  365.     {"L", NULL},
  366.     LARG_NO,
  367.     {NULL}
  368.   },
  369.   {
  370.     SYM_LICENSE3,
  371.     "copyright",
  372.     {"L", NULL},
  373.     LARG_NO,
  374.     {NULL}
  375.   },
  376. #if USE_RC
  377.   {
  378.     SYM_DATE_VARIABLE1,
  379.     "date-variable",
  380.     {"v", NULL},
  381.     LARG_ONE,
  382.     {NULL}
  383.   },
  384. #endif
  385.   {
  386.     SYM_DEBUG,
  387.     "debug",
  388.     {"0", "1", "2", "3", "4", NULL},
  389.     LARG_NO_OR_ONE,
  390.     {"internal", "handled", "unhandled", "all", "abort", NULL}
  391.   },
  392. #if USE_RC
  393.   {
  394.     SYM_DESC_FIXED_DATES,
  395.     "descending-fixed-dates",
  396.     {"c-", "C-", NULL},
  397.     LARG_NO_OR_ONE,
  398.     {"short", "long", NULL}
  399.   },
  400. #endif
  401.   {
  402.     SYM_DESC_HOLIDAY_LIST,
  403.     "descending-holiday-list",
  404.     {"n-", "N-", NULL},
  405.     LARG_NO_OR_ONE,
  406.     {"long", "short", NULL}
  407.   },
  408.   {
  409.     SYM_DISABLE_HIGHLIGHTING,
  410.     "disable-highlighting",
  411.     {"Hno", NULL},
  412.     LARG_NO,
  413.     {NULL}
  414.   },
  415. #if USE_RC
  416.   {
  417.     SYM_EXCLUDE_RC_TITLE,
  418.     "exclude-fixed-dates-list-title",
  419.     {"cx", NULL},
  420.     LARG_NO,
  421.     {NULL}
  422.   },
  423. #endif
  424.   {
  425.     SYM_EXCLUDE_HD_TITLE,
  426.     "exclude-holiday-list-title",
  427.     {"X", NULL},
  428.     LARG_NO,
  429.     {NULL}
  430.   },
  431. #if USE_RC
  432.   {
  433.     SYM_FIXED_DATES,
  434.     "fixed-dates",
  435.     {"jc", "jcb", NULL},
  436.     LARG_ONE,
  437.     {"julian", "both", NULL}
  438.   },
  439. #endif
  440.   {
  441.     SYM_FORCE_HIGHLIGHTING,
  442.     "force-highlighting",
  443.     {"Hno", NULL},
  444.     LARG_NO,
  445.     {NULL}
  446.   },
  447. #if USE_RC
  448.   {
  449.     SYM_GROUPING_TEXT,
  450.     "grouping-text",
  451.     {"cg", NULL},
  452.     LARG_NO_OR_ONE,
  453.     {NULL}
  454.   },
  455. #endif
  456.   {
  457.     SYM_HELP,
  458.     "help",
  459.     {"h", NULL},
  460.     LARG_NO,
  461.     {NULL}
  462.   },
  463. #if USE_RC
  464.   {
  465.     SYM_HIDDEN,
  466.     "hidden",
  467.     {NULL},
  468.     LARG_NO,
  469.     {NULL}
  470.   },
  471. #endif
  472.   {
  473.     SYM_HIGHLIGHTING,
  474.     "highlighting",
  475.     {"H", NULL},
  476.     LARG_ONE,
  477.     {NULL}
  478.   },
  479.   {
  480.     SYM_HOLIDAY_DATES,
  481.     "holiday-dates",
  482.     {"jn", "jnb", NULL},
  483.     LARG_ONE,
  484.     {"julian", "both", NULL}
  485.   },
  486.   {
  487.     SYM_HOLIDAY_LIST,
  488.     "holiday-list",
  489.     {"n", "N", NULL},
  490.     LARG_NO_OR_ONE,
  491.     {"long", "short", NULL}
  492.   },
  493. #if USE_RC
  494.   {
  495.     SYM_INCLUDE_CONS_NO,
  496.     "include-consecutive-number",
  497.     {"cz", NULL},
  498.     LARG_NO,
  499.     {NULL}
  500.   },
  501.   {
  502.     SYM_INCLUDE_HOLIDAY,
  503.     "include-holidays",
  504.     {"ce", "cE", NULL},
  505.     LARG_NO_OR_ONE,
  506.     {"long", "short", NULL}
  507.   },
  508.   {
  509.     SYM_INCLUDE_FILENAME,
  510.     "include-resource-file-name",
  511.     {"ca", NULL},
  512.     LARG_NO,
  513.     {NULL}
  514.   },
  515.   {
  516.     SYM_INCLUDE_TODAY,
  517.     "include-today",
  518.     {"cd", NULL},
  519.     LARG_NO,
  520.     {NULL}
  521.   },
  522.   {
  523.     SYM_INCLUDE_WEEK_NO,
  524.     "include-week-number",
  525.     {"ck", NULL},
  526.     LARG_NO,
  527.     {NULL}
  528.   },
  529. #endif
  530.   {
  531.     SYM_LICENSE1,
  532.     "license",
  533.     {"L", NULL},
  534.     LARG_NO,
  535.     {NULL}
  536.   },
  537. #if USE_RC
  538.   {
  539.     SYM_LIST_MODE,
  540.     "list-mode",
  541.     {"l", NULL},
  542.     LARG_NO,
  543.     {NULL}
  544.   },
  545.   {
  546.     SYM_LIST_OF_FIXED_DATES,
  547.     "list-of-fixed-dates",
  548.     {"c", "C", NULL},
  549.     LARG_NO_OR_ONE,
  550.     {"short", "long", NULL}
  551.   },
  552. #endif
  553.   {
  554.     SYM_LONG_HELP1,
  555.     "long-help",
  556.     {"hh", NULL},
  557.     LARG_NO_OR_ONE,
  558.     {NULL}
  559.   },
  560.   {
  561.     SYM_MAIL,
  562.     "mail",
  563.     {"m", NULL},
  564.     LARG_ONE,
  565.     {NULL}
  566.   },
  567. #if USE_RC
  568.   {
  569.     SYM_OMIT_DATE_PART,
  570.     "omit-multiple-date-part",
  571.     {"co", NULL},
  572.     LARG_NO,
  573.     {NULL}
  574.   },
  575. #endif
  576. #if USE_PAGER
  577.   {
  578.     SYM_PAGER,
  579.     "pager",
  580.     {"p", NULL},
  581.     LARG_NO,
  582.     {NULL}
  583.   },
  584. #endif
  585. #if USE_RC
  586.   {
  587.     SYM_PERIOD,
  588.     "period-of-fixed-dates",
  589.     {"c", NULL},
  590.     LARG_ONE,
  591.     {NULL}
  592.   },
  593.   {
  594.     SYM_RESOURCE_FILE,
  595.     "resource-file",
  596.     {"f", NULL},
  597.     LARG_ONE,
  598.     {NULL}
  599.   },
  600. #endif
  601.   {
  602.     SYM_RESPONSE_FILE,
  603.     "response-file",
  604.     {"R", NULL},
  605.     LARG_ONE,
  606.     {NULL}
  607.   },
  608. #ifdef GCAL_SHELL
  609.   {
  610.     SYM_SCRIPT_FILE,
  611.     "shell-script",
  612.     {"S", NULL},
  613.     LARG_ONE,
  614.     {NULL}
  615.   },
  616. #endif
  617.   {
  618.     SYM_STARTING_DAY,
  619.     "starting-day",
  620.     {"s", NULL},
  621.     LARG_ONE,
  622.     {NULL}
  623.   },
  624.   {
  625.     SYM_SUPPRESS_CALENDAR,
  626.     "suppress-calendar",
  627.     {"u", NULL},
  628.     LARG_NO,
  629.     {NULL}
  630.   },
  631.   {
  632.     SYM_TYPE_OF_CALENDAR,
  633.     "type",
  634.     {"i", "i-", NULL},
  635.     LARG_ONE,
  636.     {"special", "standard", NULL}
  637.   },
  638.   {
  639.     SYM_LONG_HELP2,
  640.     "usage",
  641.     {"hh", NULL},
  642.     LARG_NO_OR_ONE,
  643.     {NULL}
  644.   },
  645.   {
  646.     SYM_VERSION,
  647.     "version",
  648.     {"V", NULL},
  649.     LARG_NO,
  650.     {NULL}
  651.   },
  652.   {
  653.     SYM_NIL,
  654.     NULL,
  655.     {NULL},
  656.     LARG_NO,
  657.     {NULL}
  658.   }
  659. };
  660. #ifdef GCAL_EMAIL
  661. PUBLIC FILE        *tfp=(FILE *)NULL;           /* Temporary file, which is send by mailer */
  662. #endif
  663. PUBLIC Ml_struct    month_list;                 /* Used if month/year is a list/range */
  664. PUBLIC Hls_struct   ehls1s;                     /* Effective hls 1 start (current day) */
  665. PUBLIC Hls_struct   ehls1e;                     /* Effective hls 1 end (current day) */
  666. PUBLIC Hls_struct   ehls2s;                     /* Effective hls 2 start (holiday) */
  667. PUBLIC Hls_struct   ehls2e;                     /* Effective hls 2 end (holiday) */
  668. #if HAVE_ASSERT_H
  669. PUBLIC Uint         testval;                    /* Set to INT_MAX for checking the maximum table range */
  670. #endif
  671. PUBLIC int          len_year_max;               /* String length of the maximum year able to compute */
  672. PUBLIC int          warning_level=-1;           /* --debug[=0...WARN_LVL_MAX], -1 at startup */
  673. PUBLIC int          start_day;                  /* -s<0,1...7|day name> */
  674. PUBLIC int          day;                        /* Current day */
  675. PUBLIC int          month;                      /* Current month */
  676. PUBLIC int          year;                       /* Current year */
  677. PUBLIC int          act_sec;                    /* Actual second */
  678. PUBLIC int          act_min;                    /* Actual minute */
  679. PUBLIC int          act_hour;                   /* Actual hour */
  680. PUBLIC int          act_day;                    /* Actual day */
  681. PUBLIC int          act_month;                  /* Actual month */
  682. PUBLIC int          act_year;                   /* Actual year */
  683. PUBLIC int          buf_ad;                     /* Buffer of actual day */
  684. PUBLIC int          buf_am;                     /* Buffer of actual month */
  685. PUBLIC int          buf_ay;                     /* Buffer of actual year */
  686. PUBLIC int          fiscal_month=MONTH_MIN;     /* Starting month of a fiscal year */
  687. PUBLIC int          is_tty;                     /* Is output displayed on a terminal? */
  688. PUBLIC int          is_tty1;                    /* Is output directed to channel 1? */
  689. PUBLIC int          is_tty2;                    /* Is output directed to channel 2?*/
  690. #if USE_PAGER
  691. PUBLIC int          tty_rows=-1;                /* Number of tty rows, -1 at startup */
  692. PUBLIC int          tty_cols=-1;                /* Number of tty columns, -1 at startup */
  693. #endif
  694. PUBLIC int          out_rows;                   /* Number of month rows of a year calendar */
  695. PUBLIC int          out_cols;                   /* Number of month columns of ... */
  696. PUBLIC int          fmt_len;                    /* Format lenght of a standard/julian/both day */
  697. PUBLIC int          is_leap_year;               /* Is current year a leap year? */
  698. PUBLIC int          holiday_vector[MONTH_MAX][MONTH_MAX]; /* Stores the holiday dates */
  699. PUBLIC int          len_prgr_name;              /* Length of actual program name */
  700. PUBLIC char         s[MAXLEN+1];                /* General purpose text buffer */
  701. PUBLIC char         s2[MAXLEN+1];               /* General purpose text buffer */
  702. PUBLIC char         s3[MAXLEN+1];               /* General purpose text buffer */
  703. PUBLIC char        *prgr_name=(char *)NULL;     /* Stores the actual program name */
  704. #ifdef GCAL_EPAGER
  705. PUBLIC char        *ext_pager=(char *)NULL;     /* Name of external pager program */
  706. #endif
  707. PUBLIC Bool         suppr_cal_flag=FALSE;       /* -u */
  708. PUBLIC Bool         highlight_flag=TRUE;        /* -H<yes> or -H<no> */
  709. PUBLIC Bool         cal_julian_flag=FALSE;      /* -j */
  710. PUBLIC Bool         cal_both_dates_flag=FALSE;  /* -jb */
  711. PUBLIC Bool         holiday_flag=FALSE;         /* -n|N */
  712. PUBLIC Bool         hd_legal_days_only=FALSE;   /* -N */
  713. PUBLIC Bool         hd_sort_des_flag=FALSE;     /* [-n|N]- */
  714. PUBLIC Bool         hd_julian_flag=FALSE;       /* -jn */
  715. PUBLIC Bool         hd_both_dates_flag=FALSE;   /* -jnb */
  716. PUBLIC Bool         hd_title_flag=TRUE;         /* -X */
  717. PUBLIC Bool         is_fiscal_year=FALSE;       /* ':' char found in argument (`mm':`yyyy') */
  718. PUBLIC Bool         is_3month_mode=FALSE;       /* Argument is "." or ".+" or "+-" */
  719. PUBLIC Bool         is_3month_mode2=FALSE;      /* Argument is ".." -> current quarter of actual year */
  720. PUBLIC Bool         is_ext_year=FALSE;          /* Is extended year mode? */
  721. PUBLIC Bool         is_ext_list=FALSE;          /* Is extended list mode? */
  722. PUBLIC Bool         is_ext_range=FALSE;         /* Is extended range mode? */
  723. #if USE_GER
  724. PUBLIC Bool         special_calsheet_flag=FALSE;/* -i */
  725. #else /* !USE_GER */
  726. PUBLIC Bool         special_calsheet_flag=TRUE; /* -i */
  727. #endif /* !USE_GER */
  728. #if USE_HLS
  729. PUBLIC Bool         emu_hls=FALSE;              /* Must we emulate the highlighting sequences? */
  730. #else /* !USE_HLS */
  731. PUBLIC Bool         emu_hls=TRUE;               /* Must we emulate the highlighting sequences? */
  732. #endif /* !USE_HLS */
  733. #if USE_PAGER
  734. PUBLIC Bool         pager_flag=FALSE;           /* -p */
  735. #endif
  736.  
  737.  
  738.  
  739. /*
  740.    Define local(static) variables
  741. */
  742. #ifdef GCAL_EPAGER
  743. LOCAL pid_t  child_pid;                   /* Id of child process of external pager */
  744. LOCAL int    pipe_fd[2];                  /* Pipe file descriptors */
  745. LOCAL int    sys_fd[2];                   /* Buffer of system file descriptors 0 and 1 */
  746. #endif
  747. LOCAL int    lopt_id;                     /* The index value of a long option */
  748. #ifdef GCAL_EMAIL
  749. LOCAL char  *email_adr=(char *)NULL;      /* Email address gcal's output is send to */
  750. #endif
  751. #ifdef GCAL_SHELL
  752. LOCAL char  *shl_filename=(char *)NULL;   /* File name of shell script to write -S<NAME> */
  753. #endif
  754. LOCAL char  *rsp_filename=(char *)NULL;   /* Name of response file to write -R<NAME> */
  755. LOCAL char  *hl_seq=(char *)NULL;         /* Text containing user defined highlighting sequences -H<> */
  756. LOCAL Bool   license_flag=FALSE;          /* -L */
  757. LOCAL Bool   version_flag=FALSE;          /* -V */
  758. LOCAL Bool   help_flag=FALSE;             /* -? | -h */
  759. LOCAL Bool   ext_help_flag=FALSE;         /* -?? | -hh */
  760. LOCAL Bool   year_flag=FALSE;             /* -b<1|2|3|4|6|12> */
  761. LOCAL Bool   switch_back_flag=FALSE;      /* [-i]- */
  762. LOCAL Bool   show_calendar=TRUE;          /* Must we display the calendar? */
  763.  
  764.  
  765.  
  766. /*
  767.    Program entry point
  768. */
  769. #ifdef ANSI_PROTO
  770. PUBLIC int
  771. main (int   argc,
  772.       char *argv[])
  773. #else /* !ANSI_PROTO */
  774.    PUBLIC int
  775. main (argc, argv)
  776.    int   argc;
  777.    char *argv[];
  778. #endif /* !ANSI_PROTO */
  779. /*
  780.    Perform the program   =8^)
  781. */
  782. {
  783.    auto         int     my_argc_max=MY_ARGC_MAX;
  784.    auto         int     my_argc=1;
  785.    auto         int     i=0;
  786. #if USE_RC
  787. #  ifdef GCAL_SHELL
  788. #    ifdef GCAL_EMAIL
  789.    static const char   *these_short_options_need_args="FHRSbfmsv";
  790. #    else /* !GCAL_EMAIL */
  791.    static const char   *these_short_options_need_args="FHRSbfsv";
  792. #    endif /* !GCAL_EMAIL */
  793. #  else /* !GCAL_SHELL */
  794. #    ifdef GCAL_EMAIL
  795.    static const char   *these_short_options_need_args="FHRbfmsv";
  796. #    else /* !GCAL_EMAIL */
  797.    static const char   *these_short_options_need_args="FHRbfsv";
  798. #    endif /* !GCAL_EMAIL */
  799. #  endif /* !GCAL_SHELL */
  800. #else /* !USE_RC */
  801. #  ifdef GCAL_SHELL
  802. #    ifdef GCAL_EMAIL
  803.    static const char   *these_short_options_need_args="HRSbms";
  804. #    else /* !GCAL_EMAIL */
  805.    static const char   *these_short_options_need_args="HRSbs";
  806. #    endif /* !GCAL_EMAIL */
  807. #  else /* !GCAL_SHELL */
  808. #    ifdef GCAL_EMAIL
  809.    static const char   *these_short_options_need_args="HRbms";
  810. #    else /* !GCAL_EMAIL */
  811.    static const char   *these_short_options_need_args="HRbs";
  812. #    endif /* !GCAL_EMAIL */
  813. #  endif /* !GCAL_SHELL */
  814. #endif /* !USE_RC */
  815.    auto         char  **my_argv=(char **)NULL;
  816. #ifdef GCAL_EMAIL
  817.    auto         char   *tfn=(char *)NULL;
  818. #endif
  819.    auto         char   *ptr_char;
  820.  
  821.  
  822.    /*
  823.       Compute the string length of the maximum year able to compute
  824.    */
  825.    sprintf(s, "%d", YEAR_MAX);
  826.    len_year_max = (int)strlen(s);
  827. #if HAVE_ASSERT_H
  828.    /*
  829.       Perform some assertations for safe program operation...
  830.    */
  831.    testval = ~0;
  832.    testval >>= 1;
  833.    /*
  834.       Check if value for maximum number of table entries
  835.         fits to the positive range of a signed int (INT_MAX)!!
  836.    */
  837.    assert(my_argc_max>0);
  838.    assert((Uint)my_argc_max<=testval);
  839. #  if DEBUG
  840.    assert(len_year_max<11);
  841.    assert(len_year_max>0);
  842.    assert(YEAR_MAX>=YEAR_MIN);
  843.    assert(MONTH_MAX==12);
  844.    assert(CENTURY==1900);
  845.    /*
  846.       For safe program operation, BUF_LEN must be 1 minimum!!
  847.    */
  848.    assert(BUF_LEN>=1);
  849.    /*
  850.       For safe program operation, MAXLEN must be 256 minimum!!
  851.    */
  852.    assert(MAXLEN>=256);
  853.    assert(strlen(PRGR_NAME)<7);
  854.    assert(strlen(PRGR_NAME)>0);
  855.    assert(strlen(VERSION_NO)>0);
  856.    assert(MY_ARGC_MAX>1);
  857.    assert(HD_ELEMS_MAX>0);
  858. #  endif
  859. #endif /* HAVE_ASSERT_H */
  860.    /*
  861.       Test if program output is redirected/piped
  862.    */
  863. #if USE_PAGER
  864.    is_tty1 = isatty(1);
  865.    is_tty2 = isatty(2);
  866.    is_tty = (   is_tty1
  867.              && is_tty2);
  868. #  ifdef GCAL_EPAGER
  869.    if (is_tty)
  870.     {
  871.       /*
  872.          Store the sys-stdin/sys-stdout file descriptors
  873.       */
  874.       dup2(0, sys_fd[0]);
  875.       dup2(1, sys_fd[1]);
  876.     }
  877. #  endif
  878. #else /* !USE_PAGER */
  879.    is_tty = (int)TRUE;
  880. #endif /* !USE_PAGER */
  881.    /*
  882.       Detect the own program name
  883.    */
  884.    strncpy(s3, argv[0], MAXLEN+1);
  885.    s3[MAXLEN] = '\0';
  886. #ifdef SUFFIX_SEP
  887.    /*
  888.       Eliminate version suffix under VMS
  889.    */
  890.    ptr_char = strrchr(s3, *SUFFIX_SEP);
  891.    if (ptr_char != (char *)NULL)
  892.      *ptr_char = '\0';
  893. #endif
  894.    len_prgr_name = (int)strlen(s3);
  895. #ifdef DJG
  896.    ptr_char = strrchr(s3, *DIR2_SEP);
  897. #else /* !DJG */
  898.    ptr_char = strrchr(s3, *DIR_SEP);
  899. #endif /* !DJG */
  900.    if (ptr_char != (char *)NULL)
  901.     {
  902.       ptr_char++;
  903.       len_prgr_name = (int)strlen(ptr_char);
  904.     }
  905.    else
  906.      ptr_char = s3;
  907.    if (tolower('A') == 'a')
  908.     {
  909.       auto char  *buf_ptr_char=ptr_char;
  910.  
  911.  
  912.       for ( ; *ptr_char ; ptr_char++)
  913.         *ptr_char = (char)tolower(*ptr_char);
  914.       ptr_char = buf_ptr_char;
  915.     }
  916.    /*
  917.       Suppress .exe suffix for MSDOS, OS/2 and VMS
  918.    */
  919.    if (   (len_prgr_name > 4)
  920.        && !strcmp(ptr_char+len_prgr_name-4, ".exe"))
  921.     {
  922.       len_prgr_name -= 4;
  923.       *(ptr_char + len_prgr_name) = '\0';
  924.     }
  925.    /*
  926.       Maximum length of actual program name is 6 characters
  927.    */
  928.    if (len_prgr_name > 6)
  929.     {
  930.       len_prgr_name = 6;
  931.       *(ptr_char + len_prgr_name) = '\0';
  932.     }
  933.    prgr_name = (char *)my_malloc (len_prgr_name+1,
  934.                                   124, __FILE__, __LINE__ -1,
  935.                                   "prgr_name", 0);
  936.    strcpy(prgr_name, ptr_char);
  937.    /*
  938.       Initial memory allocation for `my_argv[]'
  939.    */
  940.    my_argv = (char **)my_malloc (MY_ARGC_MAX*sizeof(char *),
  941.                                  124, __FILE__, __LINE__ -1,
  942.                                  "my_argc", MY_ARGC_MAX);
  943. #if !defined(AMIGA) || defined(__GNUC__)
  944.    /*
  945.       Detect whether the GCAL environment variable is set
  946.    */
  947.    ptr_char = getenv(ENV_VAR_GCAL);
  948.    if (ptr_char != (char *)NULL)
  949.     {
  950.       if (*ptr_char)
  951.        {
  952.          /*
  953.             GCAL environment variable defined and not empty: copy the OPTIONS
  954.               expanded @file argument or actual date modifier %... argument only;
  955.               found in environment variable GCAL; into private `my_argv'
  956.          */
  957.          while (MY_ISSPACE(*ptr_char))
  958.            ptr_char++;
  959.          i = 0;
  960.          while (*ptr_char)
  961.           {
  962.             if (i < MAXLEN)
  963.               s[i++] = *ptr_char++;
  964.             if (   !*ptr_char
  965.                 || MY_ISSPACE(*ptr_char))
  966.              {
  967.                s[i] = '\0';
  968.                if (   *s == *SWITCH
  969.                    || *s == *SWITCH2
  970. #  if USE_RC
  971.                    || *s == RC_ADATE_CHAR
  972. #  endif
  973.                    || *s == RSP_CHAR)
  974.                 {
  975.                   /*
  976.                      Avoid one or two letter combinitions of '-', '/', '%' or '@' characters only!
  977.                   */
  978.                   if (   i == 1
  979.                       || (   (i == 2)
  980.                           && (   s[1] == *SWITCH
  981. #  if USE_RC
  982.                               || s[1] == RC_ADATE_CHAR
  983. #  endif
  984.                               || s[1] == *SWITCH2)))
  985.                     ;   /* Void, don't allocate memory */
  986.                   else
  987.                    {
  988.                      if (*s == RSP_CHAR)
  989.                       {
  990.                         /*
  991.                            Try to manage a response file "@file" argument given
  992.                              in environment variable GCAL.
  993.                         */
  994.                         strncpy(s3, s+1, MAXLEN+1);
  995.                         s3[MAXLEN] = '\0';
  996.                         insert_response_file (s3, these_short_options_need_args,
  997.                                               &my_argc_max, &my_argc, my_argv);
  998.                       }
  999.                      else
  1000.                       {
  1001.                         /*
  1002.                            Ok, argument is an option or an actual date modifier %...
  1003.                         */
  1004.                         if (   (   *s == *SWITCH
  1005.                                 || *s == *SWITCH2)
  1006.                             && (s[1] != *SWITCH))
  1007.                          {
  1008.                            /*
  1009.                               Short-style option found
  1010.                            */
  1011.                            if (strchr(these_short_options_need_args, s[1]) != (char *)NULL)
  1012.                             {
  1013.                               /*
  1014.                                  Short-style option requires an argument, which could be separated
  1015.                                    by whitespace characters from the option character; respect this!
  1016.                                    this means all separating whitespace characters between the
  1017.                                    option character and argument will be eliminated.
  1018.                               */
  1019.                               while (MY_ISSPACE(*ptr_char))
  1020.                                 ptr_char++;   /* Skip the separating whitespace characters. */
  1021.                               /*
  1022.                                  Store needed argument of option adjacent to option character.
  1023.                               */
  1024.                               while (   (i < MAXLEN)
  1025.                                      && *ptr_char
  1026.                                      && !MY_ISSPACE(*ptr_char))
  1027.                                 s[i++] = *ptr_char++;
  1028.                              }
  1029.                            s[i] = '\0';
  1030.                          }
  1031.                         if (my_argc >= my_argc_max)
  1032.                          {
  1033. #  if HAVE_ASSERT_H
  1034.                            /*
  1035.                               Check if value for maximum number of table entries
  1036.                                 fits to the positive range of a signed int(INT_MAX)!!
  1037.                            */
  1038.                            assert((Uint)my_argc_max+MY_ARGC_MAX<=testval);
  1039. #  endif
  1040.                            /*
  1041.                               Resize the table
  1042.                            */
  1043.                            my_argc_max += MY_ARGC_MAX;
  1044.                            my_argv = (char **)my_realloc (my_argv, my_argc_max*sizeof(char *),
  1045.                                                           124, __FILE__, __LINE__ -1,
  1046.                                                           "my_argc", my_argc_max);
  1047.                          }
  1048.                         my_argv[my_argc] = (char *)my_malloc (i+1,
  1049.                                                               124, __FILE__, __LINE__ -1,
  1050.                                                               "my_argc", my_argc);
  1051.                         strcpy(my_argv[my_argc++], s);
  1052.                       }
  1053.                    }
  1054.                   while (MY_ISSPACE(*ptr_char))
  1055.                     ptr_char++;
  1056.                   i = 0;
  1057.                 }
  1058.                else
  1059.                  if (i)
  1060.                   {
  1061.                     /*
  1062.                        Error, argument is a command
  1063.                     */
  1064. #  if USE_GER
  1065.                     fprintf(stderr, "%s: Kommando in Umgebungsvariable `"ENV_VAR_GCAL
  1066.                             "' angegeben -- %s\n", prgr_name, s);
  1067. #  else /* !USE_GER */
  1068.                     fprintf(stderr, "%s: command in environment variable `"ENV_VAR_GCAL
  1069.                             "' found -- %s\n", prgr_name, s);
  1070. #  endif /* !USE_GER */
  1071.                     fprintf(stderr, "%s\n", usage_msg ());
  1072.                     put_longopt_description (stderr);
  1073.                     S_NEWLINE(stderr);
  1074.                     exit(126);
  1075.                   }
  1076.              }
  1077.           }
  1078.        }
  1079.     }
  1080. #endif /* !AMIGA || __GNUC__ */
  1081.    /*
  1082.       Now insert/append the "arguments" of command line
  1083.         into private `my_argv'
  1084.    */
  1085.    while (argc > 1)
  1086.     {
  1087.       ++argv;
  1088.       /*
  1089.          Preload contents of response files and don't place this option
  1090.            text itself in private `my_argc' command line options vector!
  1091.       */
  1092.       if (**argv == RSP_CHAR)
  1093.        {
  1094.          /*
  1095.             Try to manage a response file "@file" argument given in command line.
  1096.          */
  1097.          strncpy(s3, *argv+1, MAXLEN+1);
  1098.          s3[MAXLEN] = '\0';
  1099.          insert_response_file (s3, these_short_options_need_args,
  1100.                                &my_argc_max, &my_argc, my_argv);
  1101.        }
  1102.       else
  1103.        {
  1104.          register int  len=(int)strlen(*argv);
  1105.  
  1106.  
  1107.          /*
  1108.             Avoid one or two letter combinitions of '-', '/' or '%' characters only!
  1109.          */
  1110.          if (   (   (len == 1)
  1111.                  && (   **argv == *SWITCH
  1112. #if USE_RC
  1113.                      || **argv == RC_ADATE_CHAR
  1114. #endif
  1115.                      || **argv == *SWITCH2))
  1116.              || (   (len == 2)
  1117.                  && (   **argv == *SWITCH
  1118. #if USE_RC
  1119.                      || **argv == RC_ADATE_CHAR
  1120. #endif
  1121.                      || **argv == *SWITCH2)
  1122.                  && (   *(*argv+1) == *SWITCH
  1123. #if USE_RC
  1124.                      || *(*argv+1) == RC_ADATE_CHAR
  1125. #endif
  1126.                      || *(*argv+1) == *SWITCH2)))
  1127.            ;   /* Void, don't allocate memory */
  1128.          else
  1129.           {
  1130.             if (my_argc >= my_argc_max)
  1131.              {
  1132. #if HAVE_ASSERT_H
  1133.                /*
  1134.                   Check if value for maximum number of table entries
  1135.                     fits to the positive range of a signed int(INT_MAX)!!
  1136.                */
  1137.                assert((Uint)my_argc_max+MY_ARGC_MAX<=testval);
  1138. #endif
  1139.                /*
  1140.                   Resize the table
  1141.                */
  1142.                my_argc_max += MY_ARGC_MAX;
  1143.                my_argv = (char **)my_realloc (my_argv, my_argc_max*sizeof(char *),
  1144.                                               124, __FILE__, __LINE__ -1,
  1145.                                               "my_argc", my_argc_max);
  1146.              }
  1147.             my_argv[my_argc] = (char *)my_malloc (len+1,
  1148.                                                   124, __FILE__, __LINE__ -1,
  1149.                                                   "my_argc", my_argc);
  1150.             strcpy(my_argv[my_argc++], *argv);
  1151.           }
  1152.        }
  1153.       argc--;
  1154.     }
  1155.    /*
  1156.       Building of private `*my_argv[]' is complete, so check first whether
  1157.         warning/debug option (--debug[=0...WARN_LVL_MAX]) is given (needed to
  1158.         set correct warning level in case global date variable definitions or
  1159.         operations follow) and then check whether global date variable
  1160.         definitions/operations -v<> are given so we can reference them
  1161.         in actual date modifier, e.g., %`yyyy'@`dvar'[[-]<n>[`ww[w]']]
  1162.    */
  1163.    if (my_argc > 1)
  1164.     {
  1165.       auto int  j;
  1166.  
  1167.  
  1168.       /*
  1169.          Now it's time to rearrange `*my_argv[]', so all short-style options
  1170.            with needed argument like `-X foo' are concatenated to `-Xfoo'.
  1171.       */
  1172.       rearrange_argv (these_short_options_need_args, &my_argc, my_argv);
  1173.       i = 1;
  1174.       while (i < my_argc)
  1175.        {
  1176.          ptr_char = my_argv[i];
  1177.          if (   *ptr_char == *SWITCH
  1178.              || *ptr_char == *SWITCH2)
  1179.           {
  1180.             ptr_char++;
  1181.             if (*ptr_char == *SWITCH)
  1182.              {
  1183.                /*
  1184.                   Long option given;
  1185.                     convert it to an according short option
  1186.                */
  1187.                ptr_char++;
  1188.                strncpy(s3, ptr_char, MAXLEN+1);
  1189.                s3[MAXLEN] = '\0';
  1190.                /*
  1191.                   Set only option part to lower case
  1192.                */
  1193.                j = 0;
  1194.                while (   s3[j]
  1195.                       && (s3[j] != *LARG_SEP))
  1196.                 {
  1197.                   s3[j] = (char)tolower(s3[j]);
  1198.                   j++;
  1199.                 }
  1200.                if (!eval_longopt (s3, &lopt_id))
  1201.                  ptr_char = s3;
  1202.                else
  1203.                  /*
  1204.                     Error in given long option detected;
  1205.                       skip this long option only!
  1206.                  */
  1207.                  ptr_char = s3 + strlen(s3);
  1208.              }
  1209.             else
  1210.               lopt_id = SYM_NIL;
  1211.             if (lopt_id == SYM_DEBUG)
  1212.                warning_level = my_atoi (ptr_char);
  1213. #if USE_RC
  1214.             else
  1215.               if (*ptr_char == 'v')
  1216.                {
  1217.                  ptr_char++;
  1218.                  /*
  1219.                     Global date variable definition found
  1220.                       (e.g. -va=1227:b=0514:c=a...) so try to scan
  1221.                       argument and store found `mmdd' dates in
  1222.                       date variable vector
  1223.                  */
  1224.                  while (*ptr_char)
  1225.                   {
  1226.                     /*
  1227.                        Split the colon separated list of date variables
  1228.                     */
  1229.                     j = 0;
  1230.                     while (   *ptr_char
  1231.                            && (*ptr_char != *SEP)
  1232.                            && (j < MAXLEN))
  1233.                       s[j++] = *ptr_char++;
  1234.                     s[j] = '\0';
  1235.                     if (!set_dvar (s, RC_INTERNAL_TXT, 0, GLobal))
  1236.                       /*
  1237.                          Error, unable to store date variable
  1238.                       */
  1239.                       my_error (114, "", 0, s, 0);
  1240.                     if (*ptr_char)
  1241.                       ptr_char++;
  1242.                   }
  1243.                }
  1244. #endif /* USE_RC */
  1245.           }
  1246.          /*
  1247.             Stop processing if first command is found
  1248.          */
  1249.          if (   (*my_argv[i] != *SWITCH)
  1250. #if USE_RC
  1251.              && (*my_argv[i] != RC_ADATE_CHAR)
  1252. #endif
  1253.              && (*my_argv[i] != *SWITCH2))
  1254.            break;
  1255.          i++;
  1256.        }
  1257.     }
  1258. #if USE_RC
  1259.    /*
  1260.       Check whether actual date modifier %... is given
  1261.    */
  1262.    if (my_argc > 1)
  1263.     {
  1264.       i = 1;
  1265.       while (i < my_argc)
  1266.        {
  1267.          if (*my_argv[i] == RC_ADATE_CHAR)
  1268.            rc_adate = my_argv[i] + 1;
  1269.          /*
  1270.             Stop processing if first command is found
  1271.          */
  1272.          if (   (*my_argv[i] != *SWITCH)
  1273.              && (*my_argv[i] != *SWITCH2)
  1274.              && (*my_argv[i] != RC_ADATE_CHAR))
  1275.            break;
  1276.          i++;
  1277.        }
  1278.     }
  1279.    /*
  1280.       Read the internal system date
  1281.    */
  1282.    if (!get_actual_date ())
  1283.     {
  1284.       /*
  1285.          Error, invalid actual date modifier %... given
  1286.       */
  1287. #  if USE_GER
  1288.       fprintf(stderr, "%s: Ung"UE"ltiges Datum angegeben -- %c%s\n",
  1289.               prgr_name, RC_ADATE_CHAR, rc_adate);
  1290. #  else /* !USE_GER */
  1291.       fprintf(stderr, "%s: invalid date given -- %c%s\n",
  1292.               prgr_name, RC_ADATE_CHAR, rc_adate);
  1293. #  endif /* !USE_GER */
  1294.       fprintf(stderr, "%s\n", usage_msg ());
  1295.       put_longopt_description (stderr);
  1296.       S_NEWLINE(stderr);
  1297.       exit(126);
  1298.     }
  1299. #else /* !USE_RC */
  1300.    (void)get_actual_date ();
  1301. #endif /* !USE_RC */
  1302.    is_leap_year = (days_of_february (act_year) == 29);
  1303. #ifdef GCAL_EPAGER
  1304.    if (is_tty)
  1305.     {
  1306.       auto FILE  *fp=(FILE *)NULL;
  1307.  
  1308.  
  1309.       /*
  1310.          Try to detect the external pager program in a safe way
  1311.       */
  1312.       ptr_char = getenv(ENV_VAR_PAGER);
  1313.       if (ptr_char != (char *)NULL)
  1314.        {
  1315.          if (*ptr_char)
  1316.           {
  1317.             while (MY_ISSPACE(*ptr_char))
  1318.               ptr_char++;
  1319.             strncpy(s3, ptr_char, MAXLEN+1);
  1320.             s3[MAXLEN] = '\0';
  1321.             if (*ptr_char != *DIR_SEP)
  1322.              {
  1323.                ptr_char = strrchr(s3, *DIR_SEP);
  1324.                if (ptr_char != (char *)NULL)
  1325.                  ptr_char++;
  1326.                else
  1327.                  ptr_char = s3;
  1328.              }
  1329.             ext_pager = (char *)my_malloc (strlen(ptr_char)+1,
  1330.                                            124, __FILE__, __LINE__ -1,
  1331.                                            "ext_pager", 0);
  1332.             strcpy(ext_pager, ptr_char);
  1333.             i = 0;
  1334.             while (   ext_pager[i]
  1335.                    && !MY_ISSPACE(ext_pager[i]))
  1336.               i++;
  1337.             ext_pager[i] = '\0';
  1338.             if (*ext_pager == *DIR_SEP)
  1339.               /*
  1340.                  Absolute pager name given, search program directly
  1341.               */
  1342.               fp = fopen(ext_pager, "r");
  1343.             else
  1344.              {
  1345.                /*
  1346.                   Relative pager name given, search program in PATH
  1347.                */
  1348.                strncpy(s3, ext_pager, MAXLEN+1);
  1349.                s3[MAXLEN] = '\0';
  1350.                fp = file_open (s3, COmmon);
  1351.              }
  1352.             if (fp == (FILE *)NULL)
  1353.              {
  1354.                free(ext_pager);
  1355.                ext_pager = (char *)NULL;
  1356.              }
  1357.           }
  1358.        }
  1359.       if (ext_pager == (char *)NULL)
  1360.        {
  1361.          strncpy(s3, PAGER_PROG, MAXLEN+1);
  1362.          s3[MAXLEN] = '\0';
  1363.          fp = file_open (s3, COmmon);
  1364.          if (fp != (FILE *)NULL)
  1365.           {
  1366.             ext_pager = PAGER_PROG;
  1367.             fclose(fp);
  1368.           }
  1369.          else
  1370.           {
  1371.             strncpy(s3, PAGER2_PROG, MAXLEN+1);
  1372.             s3[MAXLEN] = '\0';
  1373.             fp = file_open (s3, COmmon);
  1374.             if (fp != (FILE *)NULL)
  1375.              {
  1376.                ext_pager = PAGER2_PROG;
  1377.                fclose(fp);
  1378.              }
  1379.           }
  1380.        }
  1381.       if (ext_pager != (char *)NULL)
  1382.        {
  1383.          /*
  1384.             We work unbuffered in this case so we have to flush stdout buffer first
  1385.          */
  1386.          fflush(stdout);
  1387.          /*
  1388.             Open unnamed pipe
  1389.          */
  1390.          if (pipe(pipe_fd) < 0)
  1391.            /*
  1392.               Error, pipe() fails
  1393.            */
  1394.            my_error (110, __FILE__, __LINE__ -4, "pipe()", 0);
  1395.          /*
  1396.             Ignore SIGPIPE signal
  1397.          */
  1398.          signal(SIGPIPE, SIG_IGN);
  1399.        }
  1400.     }
  1401. #endif /* GCAL_EPAGER */
  1402.    /*
  1403.       Check and evaluate the command line arguments and detect,
  1404.         whether the extended year/list/range mode is wanted
  1405.    */
  1406.    check_command_line (my_argc, my_argv);
  1407. #ifdef GCAL_EMAIL
  1408.    /*
  1409.       In case gcal's output must be send to a user via Email:
  1410.         create and open temporary file
  1411.    */
  1412.    if (email_adr != (char *)NULL)
  1413.     {
  1414.       tfn = tmpnam(NULL);
  1415.       if (tfn == (char *)NULL)
  1416.         my_error (111, "", 0, email_adr, 0);
  1417.       tfp = fopen(tfn, "w");
  1418.       if (tfp == (FILE *)NULL)
  1419.         my_error (111, "", 0, email_adr, 0);
  1420.       is_tty = (int)FALSE;
  1421. #  if USE_GER
  1422.       fprintf(tfp, "Subject: Post von %s "
  1423.               "(%04d/%02d/%02d %02d"TIME_SEP"%02d"TIME_SEP"%02d)\n\n",
  1424.               prgr_name, buf_ay, buf_am, buf_ad, act_hour, act_min, act_sec);
  1425. #  else /* !USE_GER */
  1426.       fprintf(tfp, "Subject: Mail from %s "
  1427.               "(%04d/%02d/%02d %02d"TIME_SEP"%02d"TIME_SEP"%02d)\n\n",
  1428.               prgr_name, buf_ay, buf_am, buf_ad, act_hour, act_min, act_sec);
  1429. #  endif /* !USE_GER */
  1430.     }
  1431. #endif /* GCAL_EMAIL */
  1432.    /*
  1433.       Check whether month calendar output is wanted
  1434.         in case no explicit date is given in command line
  1435.    */
  1436.    if (switch_back_flag)
  1437.      special_calsheet_flag = (Bool)!special_calsheet_flag;
  1438.    /*
  1439.       Do we have to suppress the output of a month calendar in case only
  1440.         the -n|N[-] flag (display eternal holiday list) is found and/or
  1441.         only the -c[] flag (display fixed date warnings) is found?
  1442.    */
  1443.    if (   !year
  1444.        && !month
  1445.        && (   holiday_flag
  1446. #if USE_RC
  1447.            || rc_use_flag
  1448. #endif
  1449.           )
  1450. #if USE_GER
  1451.        && !special_calsheet_flag
  1452. #else /* !USE_GER */
  1453.        && special_calsheet_flag
  1454. #endif /* !USE_GER */
  1455.        && (   !start_day
  1456.            || (   (start_day < DAY_MIN)
  1457. #if USE_RC
  1458.                && rc_use_flag
  1459. #endif
  1460.           ))
  1461.        && !switch_back_flag
  1462.        && !year_flag)
  1463.      show_calendar = FALSE;
  1464. #if USE_RC
  1465.    /*
  1466.       Check whether an explicit date is given in command line
  1467.    */
  1468.    is_date_given = (Bool)(   month
  1469.                           || year
  1470.                           || is_fiscal_year);
  1471. #endif
  1472.    /*
  1473.       Check whether the arguments of command line are valid
  1474.    */
  1475.    eliminate_invalid_data ();
  1476.    /*
  1477.       Get the highlighting sequences of the terminal
  1478.    */
  1479.    get_tty_hls (hl_seq);
  1480. #if USE_PAGER
  1481.    /*
  1482.       No program output yet, so if the paging option is wanted:
  1483.         set the standard stream buffers to unbuffered mode
  1484.         and get actual settings of the tty
  1485.    */
  1486.    if (   is_tty1
  1487.        && is_tty2
  1488. #  ifdef GCAL_EPAGER
  1489.        && (ext_pager == (char *)NULL)
  1490. #  endif
  1491.        && pager_flag)
  1492.     {
  1493.       setbuf(stdout, (char *)NULL);
  1494.       setbuf(stdin, (char *)NULL);
  1495.       get_tty_scr_size (&tty_rows, &tty_cols);
  1496.     }
  1497. #endif /* USE_PAGER */
  1498.    /*
  1499.       Log contents of command line:
  1500.         i.e. check whether a response file must be written
  1501.    */
  1502.    if (rsp_filename != (char *)NULL)
  1503.      write_log_file (rsp_filename, REsponse, RESPONSE_TXT, my_argc, my_argv);
  1504. #ifdef GCAL_SHELL
  1505.    /*
  1506.       Log contents of command line:
  1507.         i.e. check whether a shell script must be written
  1508.    */
  1509.    if (shl_filename != (char *)NULL)
  1510.      write_log_file (shl_filename, SCript, SCRIPT_TXT, my_argc, my_argv);
  1511. #endif /* GCAL_SHELL */
  1512. #ifdef GCAL_EPAGER
  1513.    if (   is_tty1
  1514.        && is_tty2
  1515.        && pager_flag
  1516.        && (ext_pager != (char *)NULL))
  1517.     {
  1518.       child_pid = fork();
  1519.       switch (child_pid)
  1520.        {
  1521.          case -1:
  1522.            /*
  1523.               Error, fork() fails
  1524.            */
  1525.            my_error (110, __FILE__, __LINE__ -7, "fork()", 0);
  1526.          case 0:
  1527.            /*
  1528.               Child process (read from pipe):
  1529.                 connect pipe-stdin to sys-stdin in a safe way
  1530.                 and launch external pager
  1531.            */
  1532.            close(pipe_fd[1]);
  1533.            if (pipe_fd[0])
  1534.             {
  1535.               close(0);
  1536.               dup(pipe_fd[0]);
  1537.               close(pipe_fd[0]);
  1538.             }
  1539.            execlp(ext_pager, ext_pager, (char *)NULL);
  1540.            /*
  1541.               Error, execlp() fails (this line should never be executed)
  1542.            */
  1543.            sprintf(s, "execlp(%s)", ext_pager);
  1544.            my_error (110, __FILE__, __LINE__ -5, s, 0);
  1545.          default:
  1546.            /*
  1547.               Parent process (write to pipe):
  1548.                 connect pipe-stdout to sys-stdout in a safe way
  1549.                 and initiate action
  1550.            */
  1551.            close(pipe_fd[0]);
  1552.            if (pipe_fd[1] != 1)
  1553.             {
  1554.               close(1);
  1555.               if (!dup(pipe_fd[1]))
  1556.                {
  1557.                  dup(pipe_fd[1]);
  1558.                  close(0);
  1559.                }
  1560.               close(pipe_fd[1]);
  1561.             }
  1562.        }
  1563.     }
  1564. #endif /* GCAL_EPAGER */
  1565.    /*
  1566.       And now display the calendar
  1567.    */
  1568.    if (show_calendar)
  1569.      print_calendar ();
  1570.    else
  1571.      /*
  1572.         Only the -n|N[-] flag (display eternal holiday list) is found and/or
  1573.         only the -c[] flag (display fixed date warnings) is found, display
  1574.         these list(s) without/omitting a leading month calendar
  1575.      */
  1576.     {
  1577.       register int  tmp_ad=act_day;
  1578.  
  1579.  
  1580.       is_leap_year = (days_of_february (year) == 29);
  1581.       if (is_fiscal_year)
  1582.         fiscal_month = *month_list.month;
  1583.       if (cal_julian_flag)
  1584.         act_day = day_of_year (tmp_ad, act_month, act_year);
  1585.       if (   (   (year == EASTER_MIN-1)
  1586.               && (fiscal_month > MONTH_MIN))
  1587.           || (   (year >= EASTER_MIN)
  1588.               && (year <= EASTER_MAX)))
  1589.         print_all_holidays (FALSE, TRUE);
  1590.       if (cal_julian_flag)
  1591.         act_day = tmp_ad;
  1592.     }
  1593.    /*
  1594.       If simple month-/year mode is active...
  1595.    */
  1596.    if (!month_list.month[1])
  1597.     {
  1598.       if (   is_fiscal_year
  1599.           || (   holiday_flag
  1600.               && !show_calendar))
  1601.         month = 0;
  1602. #if USE_RC
  1603.       if (rc_use_flag)
  1604.         rc_use ();
  1605. #endif
  1606.       if (holiday_flag)
  1607.        {
  1608.          if (   (   (year == EASTER_MIN-1)
  1609.                  && (fiscal_month == 1))
  1610.              || year < EASTER_MIN-1
  1611.              || year > EASTER_MAX)
  1612.            /*
  1613.               Error, invalid year given for computation of Easter Sunday's date
  1614.            */
  1615.            my_error (125, "", 0, "", 0);
  1616.          print_all_holidays (FALSE, FALSE);
  1617.        }
  1618.     }
  1619. #ifdef GCAL_EPAGER
  1620.    if (   is_tty1
  1621.        && is_tty2
  1622.        && pager_flag
  1623.        && (ext_pager != (char *)NULL))
  1624.     {
  1625.       /*
  1626.          We work unbuffered in this case so we have to flush stdout buffer
  1627.            for showing all contents of it
  1628.       */
  1629.       fflush(stdout);
  1630.       /*
  1631.          And reconnect the sys-stdin/sys-stdout file descriptors
  1632.       */
  1633.       close(0);
  1634.       dup(sys_fd[0]);
  1635.       close(1);
  1636.       dup(sys_fd[1]);
  1637.       /*
  1638.          And wait until child has performed all action
  1639.       */
  1640.       while (wait((pid_t *)NULL) != child_pid)
  1641.         ;
  1642.       /*
  1643.          Reset SIGPIPE signal
  1644.       */
  1645.       signal(SIGPIPE, SIG_DFL);
  1646.     }
  1647. #endif /* GCAL_EPAGER */
  1648. #ifdef GCAL_EMAIL
  1649.    /*
  1650.       If mailing option is selected:
  1651.         close temporary file, redirect it to mailer and then erase it
  1652.    */
  1653.    if (email_adr != (char *)NULL)
  1654.     {
  1655.       if (fclose(tfp) == EOF)
  1656.         my_error (111, "", 0, email_adr, 0);
  1657.       sprintf(s, MAIL_PRGR" %s "REDIRECT" %s", email_adr, tfn);
  1658.       if (system(s))
  1659.        {
  1660.          /*
  1661.             If the shell reports a `mail' exit status not equal 0,
  1662.               first try to erase the temporary file (or let it be if
  1663.               it fails) and terminate gcal with error message
  1664.          */
  1665.          (void)unlink(tfn);
  1666.          my_error (111, "", 0, email_adr, 0);
  1667.        }
  1668.       /*
  1669.          Ignore any errors...
  1670.       */
  1671.       (void)unlink(tfn);
  1672.     }
  1673. #endif
  1674. #if USE_RC
  1675.    if (   rc_use_flag
  1676.        && !rc_elems)
  1677.      return(1);
  1678. #endif
  1679.  
  1680.    return(0);
  1681. }
  1682.  
  1683.  
  1684.  
  1685. #ifdef ANSI_PROTO
  1686. PUBLIC int
  1687. eval_longopt (char *longopt,
  1688.               int  *longopt_symbolic)
  1689. #else /* !ANSI_PROTO */
  1690.    PUBLIC int
  1691. eval_longopt (longopt, longopt_symbolic)
  1692.    char *longopt;
  1693.    int  *longopt_symbolic;
  1694. #endif /* !ANSI_PROTO */
  1695. /*
  1696.    Evaluates a long option and returns -2...0 on success, +1...+6 if fails:
  1697.      -2 == given `longopt' successfully parsed and completed `long_name' with argument returned.
  1698.      -1 == given `longopt' successfully parsed and completed `long_name' only returned.
  1699.       0 == given `longopt' successfully parsed and corresponding `short_name' returned.
  1700.      +1 == given `longopt' is ambiguous (not distinguishable).
  1701.      +2 == given `longopt' is unknown.
  1702.      +3 == given `longopt' requires no argument.
  1703.      +4 == given `longopt' requires an argument.
  1704.      +5 == given `longopt' with invalid argument.
  1705.      +6 == given `longopt' with ambiguous argument.
  1706.    if success and `short_name[0]' isn't set to NULL, the delivered `longopt'
  1707.      is converted to an according `short_name' (UN*X-style) option and returned,
  1708.      otherwise `longopt' is returned unmodified.
  1709.    if success and `short_name[0]' is set to NULL, return the completed
  1710.      `long_name' (with possibly trailing arguments) instead.
  1711.    `longopt_symbolic' is either set to SYM_NIL if given `longopt' isn't member
  1712.      of field `long_name' of `lopt' structure or to the according SYM_???.
  1713. */
  1714. {
  1715.    auto const Lopt_struct  *ptr_lopt=&lopt[0];
  1716.  
  1717.  
  1718.    *longopt_symbolic = SYM_NIL;
  1719.    if (*longopt >= *ptr_lopt->long_name)
  1720.     {
  1721.       /*
  1722.          Check whether first character of `longopt' can be found in `lopt' structure member `long_name'.
  1723.       */
  1724.       while (*ptr_lopt->long_name < *longopt)
  1725.        {
  1726.          ptr_lopt++;
  1727.          if (ptr_lopt->long_name == NULL)
  1728.            break;
  1729.        }
  1730.       if (ptr_lopt->long_name != NULL)
  1731.        {
  1732.          if (*ptr_lopt->long_name == *longopt)
  1733.           {
  1734.             auto     const Lopt_struct  *ptr2_lopt=ptr_lopt+1;
  1735.             register       int           len_longopt=(int)strlen(longopt);
  1736.             auto           Bool          larg_sep_found;
  1737.             auto           Bool          ok=FALSE;
  1738.  
  1739.  
  1740.             if (strchr(longopt, *LARG_SEP) != NULL)
  1741.               len_longopt -= (int)strlen(strchr(longopt, *LARG_SEP));
  1742.             /*
  1743.                First character of `longopt' is found in `lopt' structure member `long_name';
  1744.                  now check for the complete long name or a significant abbreviation of it.
  1745.             */
  1746.             while (   !ok
  1747.                    && (ptr_lopt->long_name != NULL))
  1748.              {
  1749.                if (   !strncmp(ptr_lopt->long_name, longopt, len_longopt)
  1750.                    && !strncmp(ptr2_lopt->long_name, longopt, len_longopt))
  1751.                  /*
  1752.                     Error, `longopt' is ambiguous (not distinguishable).
  1753.                  */
  1754.                  return(1);
  1755.                if (strncmp(ptr_lopt->long_name, longopt, len_longopt))
  1756.                 {
  1757.                   ptr_lopt++;
  1758.                   if (ptr_lopt->long_name != NULL)
  1759.                     ptr2_lopt++;
  1760.                   if (ptr2_lopt->long_name == NULL)
  1761.                     if (!strncmp(ptr_lopt->long_name, longopt, len_longopt))
  1762.                       ok = TRUE;
  1763.                 }
  1764.                else
  1765.                  ok = TRUE;
  1766.              }
  1767.             if (!ok)
  1768.               /*
  1769.                  Error, `longopt' not found (contains a spelling mistake).
  1770.               */
  1771.               return(2);
  1772.             larg_sep_found = (Bool)(((int)strlen(longopt)-len_longopt) ? TRUE : FALSE);
  1773.             if (   larg_sep_found
  1774.                 && (ptr_lopt->larg_mode == LARG_NO))
  1775.              {
  1776.                *longopt_symbolic = ptr_lopt->symbolic_name;
  1777.                /*
  1778.                   Error, `longopt' requires no argument.
  1779.                */
  1780.                return(3);
  1781.              }
  1782.             if (   !larg_sep_found
  1783.                 && (ptr_lopt->larg_mode > LARG_NO_OR_ONE))
  1784.              {
  1785.                *longopt_symbolic = ptr_lopt->symbolic_name;
  1786.                /*
  1787.                   Error, `longopt' requires an argument.
  1788.                */
  1789.                return(4);
  1790.              }
  1791.             /*
  1792.                Valid `longopt' found.
  1793.             */
  1794.             if (   ptr_lopt->larg_mode == LARG_NO
  1795.                 || (   (ptr_lopt->larg_mode == LARG_NO_OR_ONE)
  1796.                     && !larg_sep_found))
  1797.              {
  1798.                /*
  1799.                   `longopt' requires NO argument (e.g. foo);
  1800.                     return the FIRST `short_name' of `lopt' structure if its
  1801.                     not set to NULL, otherwise return the completed `long_name'.
  1802.                */
  1803.                if (ptr_lopt->short_name[0] == NULL)
  1804.                 {
  1805.                   strcpy(longopt, ptr_lopt->long_name);
  1806.                   *longopt_symbolic = ptr_lopt->symbolic_name;
  1807.                   return(-1);
  1808.                 }
  1809.                strcpy(longopt, ptr_lopt->short_name[0]);
  1810.              }
  1811.             else
  1812.              {
  1813.                auto char  *ptr_char=longopt+len_longopt+1;
  1814.                auto char  *larg_longopt;
  1815.  
  1816.  
  1817.                /*
  1818.                   `longopt' must have ONE trailing argument (e.g. foo=BAR);
  1819.                     return the CORRESPONDING `short_name' stored in `lopt' structure.
  1820.                */
  1821.                if (!*ptr_char)
  1822.                 {
  1823.                   *longopt_symbolic = ptr_lopt->symbolic_name;
  1824.                   /*
  1825.                      Error, `longopt' isn't trailed by an argument.
  1826.                   */
  1827.                   return(4);
  1828.                 }
  1829.                larg_longopt = (char *)my_malloc (strlen(longopt)-len_longopt,
  1830.                                                  124, __FILE__, __LINE__ -1,
  1831.                                                  "larg_longopt", 0);
  1832.                strcpy(larg_longopt, ptr_char);
  1833.                if (ptr_lopt->largs[0] == NULL)
  1834.                 {
  1835.                   /*
  1836.                      Process ANY argument given.
  1837.                   */
  1838.                   if (ptr_lopt->short_name[0] == NULL)
  1839.                    {
  1840.                      /*
  1841.                         Return the completed `long_name' with given argument;
  1842.                           the format of returned `longopt' is like:  foo=BAR
  1843.                      */
  1844.                      strcpy(longopt, ptr_lopt->long_name);
  1845.                      strcat(longopt, LARG_SEP);
  1846.                      strcat(longopt, larg_longopt);
  1847.                      *longopt_symbolic = ptr_lopt->symbolic_name;
  1848.                      return(-2);
  1849.                    }
  1850.                   /*
  1851.                      Return the corresponding `short_name' with given argument;
  1852.                        the format of returned `longopt' is like:  fooBAR
  1853.                   */
  1854.                   strcpy(longopt, ptr_lopt->short_name[0]);
  1855.                   strcat(longopt, larg_longopt);
  1856.                 }
  1857.                else
  1858.                 {
  1859.                   register int  i=0;
  1860.  
  1861.  
  1862.                   /*
  1863.                      Process SPECIAL argument given.
  1864.                   */
  1865.                   ok = FALSE;
  1866.                   /*
  1867.                      Set complete `larg_longopt' to lower case.
  1868.                   */
  1869.                   while (larg_longopt[i])
  1870.                    {
  1871.                      larg_longopt[i] = (char)tolower(larg_longopt[i]);
  1872.                      i++;
  1873.                    }
  1874.                   i = 0;
  1875.                   ptr_char = ptr_lopt->largs[i++];
  1876.                   while (   !ok
  1877.                          && (ptr_char != NULL))
  1878.                    {
  1879.                      if (*ptr_char == *larg_longopt)
  1880.                       {
  1881.                         register int  j=i-1;
  1882.                         register int  len_larg=(int)strlen(larg_longopt);
  1883.  
  1884.  
  1885.                         if (!strncmp(ptr_lopt->largs[j], larg_longopt, len_larg))
  1886.                          {
  1887.                            if (len_larg == (int)strlen(ptr_lopt->largs[j]))
  1888.                              /*
  1889.                                 Exact match
  1890.                              */
  1891.                              ok = TRUE;
  1892.                            else
  1893.                             {
  1894.                               while (   !ok
  1895.                                      && (ptr_lopt->largs[i] != NULL))
  1896.                                {
  1897.                                  if (   !strncmp(ptr_lopt->largs[i], larg_longopt, len_larg)
  1898.                                      && (len_larg == (int)strlen(ptr_lopt->largs[i])))
  1899.                                    /*
  1900.                                       Exact match
  1901.                                    */
  1902.                                    ok = TRUE;
  1903.                                  i++;
  1904.                                }
  1905.                             }
  1906.                            if (!ok)
  1907.                             {
  1908.                               auto Bool  ambig=FALSE;
  1909.  
  1910.  
  1911.                               /*
  1912.                                  Given SPECIAL argument doesn't match exactly,
  1913.                                    so try to detect whether its ambiguous
  1914.                               */
  1915.                               i = j + 1;
  1916.                               while (   !ambig
  1917.                                      && (ptr_lopt->largs[i] != NULL))
  1918.                                {
  1919.                                  if (!strncmp(ptr_lopt->largs[i], larg_longopt, len_larg))
  1920.                                    ambig = TRUE;
  1921.                                  i++;
  1922.                                }
  1923.                               if (ambig)
  1924.                                {
  1925.                                  *longopt_symbolic = ptr_lopt->symbolic_name;
  1926.                                  /*
  1927.                                     Error, given SPECIAL argument is ambiguous.
  1928.                                  */
  1929.                                  return(6);
  1930.                                }
  1931.                               else
  1932.                                {
  1933.                                  /*
  1934.                                     Given SPECIAL argument is valid!
  1935.                                  */
  1936.                                  ok = TRUE;
  1937.                                  i = j + 1;
  1938.                                }
  1939.                             }
  1940.                          }
  1941.                         else
  1942.                           ptr_char = ptr_lopt->largs[i++];
  1943.                       }
  1944.                      else
  1945.                        ptr_char = ptr_lopt->largs[i++];
  1946.                    }
  1947.                   if (!ok)
  1948.                    {
  1949.                      *longopt_symbolic = ptr_lopt->symbolic_name;
  1950.                      /*
  1951.                         Error, given SPECIAL argument not found in `lopt' structure member `largs'.
  1952.                      */
  1953.                      return(5);
  1954.                    }
  1955.                   i--;
  1956.                   if (ptr_lopt->short_name[0] == NULL)
  1957.                    {
  1958.                      /*
  1959.                         Return the completed `long_name' with a completed SPECIAL argument;
  1960.                           the format of returned `longopt' is like:  foo=BAR
  1961.                      */
  1962.                      strcpy(longopt, ptr_lopt->long_name);
  1963.                      strcat(longopt, LARG_SEP);
  1964.                      strcat(longopt, ptr_lopt->largs[i]);
  1965.                      *longopt_symbolic = ptr_lopt->symbolic_name;
  1966.                      return(-2);
  1967.                    }
  1968.                   /*
  1969.                      Return the corresponding `short_name' with a converted SPECIAL argument;
  1970.                        the format of returned `longopt' is like:  fooBAR
  1971.                   */
  1972.                   strcpy(longopt, ptr_lopt->short_name[i]);
  1973.                 }
  1974.                free(larg_longopt);
  1975.              }
  1976.           }
  1977.          else
  1978.            /*
  1979.               Error, `longopt' not member of field `long_name' of `lopt' structure.
  1980.            */
  1981.            return(2);
  1982.        }
  1983.       else
  1984.         /*
  1985.            Error, `longopt' not member of field `long_name' of `lopt' structure.
  1986.         */
  1987.         return(2);
  1988.     }
  1989.    else
  1990.      /*
  1991.         Error, first entry in `lopt' structure member `long_name' greater than delivered `longopt'.
  1992.      */
  1993.      return(2);
  1994.    *longopt_symbolic = ptr_lopt->symbolic_name;
  1995.  
  1996.    return(0);
  1997. }
  1998.  
  1999.  
  2000.  
  2001. #ifdef ANSI_PROTO
  2002. LOCAL void
  2003. rearrange_argv (const char *opt_list,
  2004.                       int  *argc,
  2005.                       char *argv[])
  2006. #else /* !ANSI_PROTO */
  2007.    LOCAL void
  2008. rearrange_argv (opt_list, argc, argv)
  2009.    const char *opt_list;
  2010.          int  *argc;
  2011.          char *argv[];
  2012. #endif /* !ANSI_PROTO */
  2013. /*
  2014.    Rearranges `*argv[]' internally.
  2015.      this means, all short-style options which need an argument,
  2016.      which is separated by a whitespace character in command line
  2017.      from the short option character, e.g. `-x foo' is concatenated
  2018.      to `-xfoo'.  the short option characters which need an argument
  2019.      are given in `*opt_list'.  this function sets given `*argc' to
  2020.      the "new" rearranged amount of arguments stored in `*argv[]'.
  2021. */
  2022. {
  2023.    register int     i=*argc-1;
  2024.    register int     n=1;
  2025.    auto     char  **ptr_argv=argv;
  2026.    auto     char  **ptr2_argv;
  2027.    auto     Bool    is_modified;
  2028.  
  2029.  
  2030.    while (i)
  2031.     {
  2032.       /*
  2033.          Generally skip `argv[0]'
  2034.       */
  2035.       ptr_argv++;
  2036.       is_modified = FALSE;
  2037.       if (   **ptr_argv == *SWITCH
  2038.           || **ptr_argv == *SWITCH2)
  2039.        {
  2040.          /*
  2041.             Found an option in `*argv[]'
  2042.               (either a long-style option or a short-style option).
  2043.          */
  2044.          (*ptr_argv)++;
  2045.          if (   **ptr_argv
  2046.              && (**ptr_argv != *SWITCH))
  2047.           {
  2048.             /*
  2049.                Short-style option given, e.g. `-x' or `-Xfoo' or `-x bar'
  2050.             */
  2051.             if (strchr(opt_list, **ptr_argv) != (char *)NULL)
  2052.              {
  2053.                /*
  2054.                   The option character is found in `opt_list',
  2055.                     this means this option needs an argument.
  2056.                */
  2057.                if (i > 1)
  2058.                 {
  2059.                   /*
  2060.                      We are not working on last option stored in `*argv[]'.
  2061.                   */
  2062.                   (*ptr_argv)++;
  2063.                   /*
  2064.                      Check if option doesn't have a its argument already
  2065.                        unseparated by a whitespace character in command line,
  2066.                        e.g. is not like this `-Xfoo' option.
  2067.                   */
  2068.                   if (!**ptr_argv)
  2069.                    {
  2070.                      /*
  2071.                         Check if option is trailed by a needed argument,
  2072.                           which is the next argument in `*argv[]', e.g. `-x bar'
  2073.                      */
  2074.                      (*ptr_argv)--;
  2075.                      (*ptr_argv)--;
  2076.                      ptr2_argv = ptr_argv;
  2077.                      ptr2_argv++;
  2078.                      /*
  2079.                         Check whether this next argument in `*argv[]' is an option
  2080.                      */
  2081.                      if (   (**ptr2_argv != RSP_CHAR)
  2082. #if USE_RC
  2083.                          && (**ptr2_argv != RC_ADATE_CHAR)
  2084. #endif
  2085.                         )
  2086.                       {
  2087.                         if (   (   **ptr2_argv == *SWITCH
  2088.                                 || **ptr2_argv == *SWITCH2)
  2089.                             && (strlen(*ptr2_argv) <= 2))
  2090.                           /*
  2091.                              Next argument is definitely a simple short-style option
  2092.                                without a given modifier, e.g. `-x' or `/x'
  2093.                           */
  2094.                           (*ptr_argv)++;
  2095.                         else
  2096.                          {
  2097.                            /*
  2098.                               Next argument is no option, concatenate the short
  2099.                                 style option character and its needed argument
  2100.                            */
  2101.                            i--;
  2102.                            argv[n] = (char *)my_realloc (argv[n], strlen(*ptr_argv)+strlen(*ptr2_argv)+1,
  2103.                                                          124, __FILE__, __LINE__ -1,
  2104.                                                          "argv[n]", 0);
  2105.                            strcpy(argv[n], *ptr_argv);
  2106.                            strcat(argv[n], *ptr2_argv);
  2107.                            ptr_argv++;
  2108.                            is_modified = TRUE;
  2109.                          }
  2110.                       }
  2111.                      else
  2112.                        (*ptr_argv)++;
  2113.                    }
  2114.                   else
  2115.                     (*ptr_argv)--;
  2116.                 }
  2117.              }
  2118.           }
  2119.        }
  2120.       else
  2121.         (*ptr_argv)++;
  2122.       if (!is_modified)
  2123.        {
  2124.          /*
  2125.             Unmodified argument found in `*argv[]';
  2126.               this means, the argument we work on here is
  2127.               either a short-style option, which needs an argument, which isn't given
  2128.               or     a short-style option, which already contains its argument like `-Xfoo'
  2129.               or     a simple short-style option like `-x'
  2130.               or     a long-style option like `--foo'...
  2131.               or     a command (an argument not leaded by a '-', '/', '@' or '%' character.
  2132.          */
  2133.          (*ptr_argv)--;
  2134.          argv[n] = (char *)my_realloc (argv[n], strlen(*ptr_argv)+1,
  2135.                                        124, __FILE__, __LINE__ -1,
  2136.                                        "argv[n]", 0);
  2137.          strcpy(argv[n], *ptr_argv);
  2138.        }
  2139.       n++;
  2140.       i--;
  2141.     }
  2142.    *argc = n;
  2143. }
  2144.  
  2145.  
  2146.  
  2147. #ifdef ANSI_PROTO
  2148. LOCAL void
  2149. check_command_line (int   argc,
  2150.                     char *argv[])
  2151. #else /* !ANSI_PROTO */
  2152.    LOCAL void
  2153. check_command_line (argc, argv)
  2154.    int   argc;
  2155.    char *argv[];
  2156. #endif /* !ANSI_PROTO */
  2157. /*
  2158.    Gets the arguments from the command line
  2159. */
  2160. {
  2161.    register int    opt_error=0;
  2162.    auto     int    i;
  2163.    auto     int    lopt_help;
  2164.    auto     char  *option=(char *)NULL;
  2165.    auto     Bool   is_longopt;
  2166.    auto     Bool   skip_option;
  2167. #if USE_RC
  2168.    auto     Bool   further_check;
  2169. #endif
  2170.  
  2171.  
  2172.    /*
  2173.       Work on arguments found in command line
  2174.    */
  2175.    while (argc > 1)
  2176.     {
  2177.       option = *++argv;
  2178.       /*
  2179.          If leading switch character is found,
  2180.            check the command line for options
  2181.       */
  2182.       if (   *option == *SWITCH
  2183.           || *option == *SWITCH2)
  2184.        {
  2185.          is_longopt = FALSE;
  2186.          /*
  2187.             Check the command line for options
  2188.          */
  2189.          for (option++ ; *option ; option++)
  2190.           {
  2191.             skip_option = FALSE;
  2192. #if USE_RC
  2193.             further_check = FALSE;
  2194. #endif
  2195.             /*
  2196.                Check for long options, e.g. --help ...
  2197.             */
  2198.             if (*option == *SWITCH)
  2199.              {
  2200.                is_longopt = TRUE;
  2201.                option++;
  2202.                if (*option)
  2203.                 {
  2204.                   i = 0;
  2205.                   strncpy(s2, option, MAXLEN+1);
  2206.                   s2[MAXLEN] = '\0';
  2207.                   /*
  2208.                      Set only option part to lower case
  2209.                   */
  2210.                   while (   s2[i]
  2211.                          && (s2[i] != *LARG_SEP))
  2212.                    {
  2213.                      s2[i] = (char)tolower(s2[i]);
  2214.                      i++;
  2215.                    }
  2216.                   opt_error = eval_longopt (s2, &lopt_id);
  2217.                   if (opt_error < 1)
  2218.                    {
  2219.                      opt_error = 0;
  2220. #if USE_RC
  2221.                      if (lopt_id == SYM_HIDDEN)
  2222.                        rc_nzero_ldvar_flag = TRUE;
  2223.                      else
  2224.                       {
  2225. #endif
  2226.                         if (lopt_id == SYM_DEBUG)
  2227.                           ;   /* Void, --debug[=0...WARN_LVL_MAX] already managed in main() */
  2228.                         else
  2229.                          {
  2230.                            option = s2;
  2231.                            /*
  2232.                               Now we have decoded a long option into the according short option form...
  2233.                               let's JUMP to that part where the short options are processed (to JUMP
  2234.                               isn't very good coding style, but its the easiest to do now  =:^)
  2235.                            */
  2236.                            goto LABEL_short_option;
  2237.                          }
  2238. #if USE_RC
  2239.                       }
  2240. #endif
  2241.                    }
  2242.                 }
  2243.                else
  2244.                  /*
  2245.                     Error, no long option name given
  2246.                       (this case can't occur anymore!!)
  2247.                  */
  2248.                  opt_error = 2;
  2249.                skip_option = TRUE;
  2250.              }
  2251.             else
  2252.               /*
  2253.                  Check for short options...
  2254.               */
  2255. LABEL_short_option:
  2256.               switch (*option)
  2257.                {
  2258.                  case '?':
  2259.                  case 'h':
  2260.                    help_flag = TRUE;
  2261.                    option++;
  2262.                    if (*option)
  2263.                     {
  2264.                       if (   *option == '?'
  2265.                           || *option == 'h')
  2266.                        {
  2267.                          ext_help_flag = TRUE;
  2268.                          lopt_help = SYM_NIL;
  2269.                          option++;
  2270.                          if (   *option
  2271.                              && is_longopt)
  2272.                           {
  2273.                             strncpy(s3, option, MAXLEN+1);
  2274.                             s3[MAXLEN] = '\0';
  2275.                             /*
  2276.                                Set only option part to lower case
  2277.                             */
  2278.                             i = 0;
  2279.                             while (   s3[i]
  2280.                                    && (s3[i] != *LARG_SEP))
  2281.                              {
  2282.                                s3[i] = (char)tolower(s3[i]);
  2283.                                i++;
  2284.                              }
  2285.                             /*
  2286.                                Check out if an argument to long option is given
  2287.                             */
  2288.                             (void)eval_longopt (s3, &lopt_help);
  2289.                             if (lopt_help == SYM_NIL)
  2290.                               /*
  2291.                                  Error, no help related to this argument found
  2292.                               */
  2293.                               opt_error = 5;
  2294.                           }
  2295.                          else
  2296.                            if (*option)
  2297.                              /*
  2298.                                 Error, invalid option modifier given
  2299.                              */
  2300.                              opt_error = 2;
  2301.                        }
  2302.                       else
  2303.                         /*
  2304.                            Error, no semi-long option name -?? or -hh given
  2305.                         */
  2306.                         opt_error = 2;
  2307.                     }
  2308.                    skip_option = TRUE;
  2309.                    break;
  2310.                  case 'L':
  2311.                    option++;
  2312.                    if (!*option)
  2313.                      license_flag=skip_option = TRUE;
  2314.                    else
  2315.                      /*
  2316.                         Error, invalid option modifier given
  2317.                      */
  2318.                      opt_error = 2;
  2319.                    break;
  2320.                  case 'V':
  2321.                    option++;
  2322.                    if (!*option)
  2323.                      version_flag=skip_option = TRUE;
  2324.                    else
  2325.                      /*
  2326.                         Error, invalid option modifier given
  2327.                      */
  2328.                      opt_error = 2;
  2329.                    break;
  2330.                  case 'R':
  2331.                    option++;
  2332.                    if (*option)
  2333.                     {
  2334.                       rsp_filename = (char *)my_realloc (rsp_filename, strlen(option)+1,
  2335.                                                          124, __FILE__, __LINE__ -1,
  2336.                                                          "rsp_filename", 0);
  2337.                       strcpy(rsp_filename, option);
  2338.                     }
  2339.                    else
  2340.                      /*
  2341.                         Error, option character is not trailed by an argument
  2342.                      */
  2343.                      opt_error = 4;
  2344.                    skip_option = TRUE;
  2345.                    break;
  2346. #ifdef GCAL_SHELL
  2347.                  case 'S':
  2348.                    option++;
  2349.                    if (*option)
  2350.                     {
  2351.                       shl_filename = (char *)my_realloc (shl_filename, strlen(option)+1,
  2352.                                                          124, __FILE__, __LINE__ -1,
  2353.                                                          "shl_filename", 0);
  2354.                       strcpy(shl_filename, option);
  2355.                     }
  2356.                    else
  2357.                      /*
  2358.                         Error, option character is not trailed by an argument
  2359.                      */
  2360.                      opt_error = 4;
  2361.                    skip_option = TRUE;
  2362.                    break;
  2363. #endif /* GCAL_SHELL */
  2364. #if USE_RC
  2365.                  case 'v':
  2366.                    /*
  2367.                      If the define_global_date_variable option -v<def:def...> is given,
  2368.                        skip/ignore that option because it's already managed by main()
  2369.                        only check if NO definitions are given because this is an error...
  2370.                    */
  2371.                    option++;
  2372.                    if (!*option)
  2373.                      /*
  2374.                         Error, option character is not trailed by an argument
  2375.                      */
  2376.                      opt_error = 4;
  2377.                    skip_option = TRUE;
  2378.                    break;
  2379. #endif /* USE_RC */
  2380.                  case 'u':
  2381.                    option++;
  2382.                    if (!*option)
  2383.                      suppr_cal_flag=skip_option = TRUE;
  2384.                    else
  2385.                      /*
  2386.                         Error, invalid option modifier given
  2387.                      */
  2388.                      opt_error = 2;
  2389.                    break;
  2390. #if USE_PAGER
  2391.                  case 'p':
  2392.                    option++;
  2393.                    if (!*option)
  2394.                      pager_flag=skip_option = TRUE;
  2395.                    else
  2396.                      /*
  2397.                         Error, invalid option modifier given
  2398.                      */
  2399.                      opt_error = 2;
  2400.                    break;
  2401. #endif
  2402.                  case 'H':
  2403.                    option++;
  2404.                    if (!*option)
  2405.                      /*
  2406.                         Error, option character is not trailed by an argument
  2407.                      */
  2408.                      opt_error = 4;
  2409.                    else                    
  2410.                     {
  2411.                       i = (int)strlen(option);
  2412.                       /*
  2413.                          Check if special argument `no' is given
  2414.                            if only `long-option=NO' instead of
  2415.                            `short-optionNO' too should be valid,
  2416.                            extend following if() like:  if (is_longopt && ...
  2417.                       */
  2418.                       if (   (i == 2)
  2419.                           && (tolower(*option) == 'n')
  2420.                           && (tolower(*(option+1)) == 'o'))
  2421.                         highlight_flag = FALSE;
  2422.                       else
  2423.                         /*
  2424.                            Check if special argument `yes' is given
  2425.                              if only `long-option=YES' instead of
  2426.                              `short-optionYES' too should be valid,
  2427.                              extend following if() like:  if (is_longopt && ...
  2428.                         */
  2429.                         if (   (i == 3)
  2430.                             && (tolower(*option) == 'y')
  2431.                             && (tolower(*(option+1)) == 'e')
  2432.                             && (tolower(*(option+2)) == 's'))
  2433.                          {
  2434.                            highlight_flag = TRUE;
  2435.                            is_tty = (int)TRUE;
  2436.                          }
  2437.                         else
  2438.                          {
  2439.                            hl_seq = (char *)my_realloc (hl_seq, strlen(option)+1,
  2440.                                                         124, __FILE__, __LINE__ -1,
  2441.                                                         "hl_seq", 0);
  2442.                            strcpy(hl_seq, option);
  2443.                            highlight_flag = TRUE;
  2444.                          }
  2445.                     }
  2446.                    skip_option = TRUE;
  2447.                    break;
  2448.                  case 'i':
  2449.                    suppr_cal_flag = FALSE;
  2450.                    option++;
  2451. #if USE_GER
  2452.                    special_calsheet_flag = TRUE;
  2453. #else /* !USE_GER */
  2454.                    special_calsheet_flag = FALSE;
  2455. #endif /* !USE_GER */
  2456.                    if (*option)
  2457.                     {
  2458.                       if (*option == '-')
  2459.                        {
  2460.                          switch_back_flag = TRUE;
  2461.                          option++;
  2462.                          if (*option)
  2463.                            /*
  2464.                               Error, option character is trailed by invalid argument
  2465.                            */
  2466.                            opt_error = 5;
  2467.                        }
  2468.                       else
  2469.                         /*
  2470.                            Error, option character is trailed by invalid modifier
  2471.                         */
  2472.                         opt_error = 5;
  2473.                     }
  2474.                    else
  2475.                      switch_back_flag = FALSE;
  2476.                    option--;
  2477.                    break;
  2478.                  case 'n':
  2479.                  case 'N':
  2480.                    holiday_flag = TRUE;
  2481.                    hd_sort_des_flag = FALSE;
  2482.                    hd_legal_days_only = (Bool)((*option == 'N') ? TRUE : FALSE);
  2483.                    option++;
  2484.                    if (*option)
  2485.                     {
  2486.                       if (*option == *DES_LIT)
  2487.                         hd_sort_des_flag = TRUE;
  2488.                       else
  2489.                         /*
  2490.                            Error, option character is trailed by invalid modifier
  2491.                         */
  2492.                         opt_error = 5;
  2493.                     }
  2494.                    skip_option = TRUE;
  2495.                    break;
  2496.                  case 'X':
  2497.                    option++;
  2498.                    if (!*option)
  2499.                     {
  2500.                       hd_title_flag = FALSE;
  2501.                       skip_option = TRUE;
  2502.                     }
  2503.                    else
  2504.                      /*
  2505.                         Error, invalid option modifier given
  2506.                      */
  2507.                      opt_error = 2;
  2508.                    break;
  2509.                  case 'j':
  2510.                    option++;
  2511.                    if (!*option)
  2512.                     {
  2513.                       cal_julian_flag = TRUE;
  2514.                       cal_both_dates_flag = FALSE;
  2515.                     }
  2516.                    else
  2517.                     {
  2518.                       if (*option == 'b')
  2519.                        {
  2520.                          option++;
  2521.                          if (!*option)
  2522.                           {
  2523.                             cal_julian_flag = FALSE;
  2524.                             cal_both_dates_flag = TRUE;
  2525.                           }
  2526.                          else
  2527.                            /*
  2528.                               Error, option character is trailed by an invalid modifier
  2529.                            */
  2530.                            opt_error = 5;
  2531.                        }
  2532.                       else
  2533.                        {
  2534.                          switch (*option)
  2535.                           {
  2536.                             case 'n':
  2537.                               option++;
  2538.                               if (!*option)
  2539.                                 hd_julian_flag = TRUE;
  2540.                               else
  2541.                                 if (*option == 'b')
  2542.                                   hd_both_dates_flag = TRUE;
  2543.                                 else
  2544.                                   /*
  2545.                                      Error, option character is trailed by an invalid modifier
  2546.                                   */
  2547.                                   opt_error = 5;
  2548.                               break;
  2549. #if USE_RC
  2550.                             case 'c':
  2551.                               option++;
  2552.                               if (!*option)
  2553.                                 rc_julian_flag = TRUE;
  2554.                               else
  2555.                                 if (*option == 'b')
  2556.                                   rc_both_dates_flag = TRUE;
  2557.                                 else
  2558.                                   /*
  2559.                                      Error, option character is trailed by an invalid modifier
  2560.                                   */
  2561.                                   opt_error = 5;
  2562.                               break;
  2563. #endif
  2564.                             default:
  2565.                               /*
  2566.                                  Error, option character is trailed by an invalid modifier
  2567.                               */
  2568.                               opt_error = 5;
  2569.                           }
  2570.                        }
  2571.                     }
  2572.                    if (!*option)
  2573.                      option--;
  2574.                    break;
  2575.                  case 'b':
  2576.                    year_flag = TRUE;
  2577.                    option++;
  2578.                    if (*option == '0')
  2579.                     {
  2580.                       while (*option == '0')
  2581.                         option++;
  2582.                       if (!*option)
  2583.                         option--;
  2584.                     }
  2585.                    out_rows = my_atoi (option);
  2586.                    if (   out_rows > MONTH_MAX
  2587.                        || out_rows < MONTH_MIN
  2588.                        || out_rows == 5
  2589.                        || (   (out_rows > 6)
  2590.                            && (out_rows < MONTH_MAX)))
  2591.                     {
  2592.                       if (!*option)
  2593.                         /*
  2594.                            Error, option character is not trailed by an argument
  2595.                         */
  2596.                         opt_error = 4;
  2597.                       else
  2598.                         /*
  2599.                            Error, option character is trailed by an invalid argument 
  2600.                         */
  2601.                         opt_error = 5;
  2602.                     }
  2603.                    else
  2604.                      skip_option = TRUE;
  2605.                    suppr_cal_flag = FALSE;
  2606.                    break;
  2607.                  case 's':
  2608.                    option++;
  2609.                    if (!*option)
  2610.                      /*
  2611.                         Error, option character is not trailed by an argument
  2612.                      */
  2613.                      opt_error = 4;
  2614.                    else
  2615.                     {
  2616.                       start_day = my_atoi (option);
  2617.                       /*
  2618.                          Check for delivered weekday name
  2619.                       */
  2620.                       if (!start_day)
  2621.                         start_day = compare_d_m_name (option, DAy);
  2622.                       if (   !start_day
  2623.                           && isdigit(*option))
  2624.                         start_day = -1;   /* Special value */
  2625.                       else
  2626.                         if (   start_day > DAY_MAX
  2627.                             || start_day < DAY_MIN)
  2628.                           /*
  2629.                              Error, option character is trailed by an invalid argument 
  2630.                           */
  2631.                           opt_error = 5;
  2632.                       suppr_cal_flag = FALSE;
  2633.                     }
  2634.                    skip_option = TRUE;
  2635.                    break;
  2636. #if USE_RC
  2637.                  case 'f':
  2638.                  case 'F':
  2639.                    if (*option == 'F')
  2640.                      rc_all_dates_flag = TRUE;
  2641.                    option++;
  2642.                    if (*option)
  2643.                     {
  2644.                       rc_filename = (char *)my_realloc (rc_filename, strlen(option)+1,
  2645.                                                         124, __FILE__, __LINE__ -1,
  2646.                                                         "rc_filename", 0);
  2647.                       strcpy(rc_filename, option);
  2648.                       rc_use_flag=skip_option = TRUE;
  2649.                     }
  2650.                    else
  2651.                      /*
  2652.                         Error, option character is not trailed by an argument
  2653.                      */
  2654.                      opt_error = 4;
  2655.                    break;
  2656.                  case 'g':
  2657.                    if (   !rc_use_flag
  2658.                        && !is_longopt)
  2659.                      /*
  2660.                         Error, given stand-alone option actually invalid
  2661.                      */
  2662.                      opt_error = 2;
  2663.                    else
  2664.                     {
  2665.                       option++;
  2666.                       if (*option)
  2667.                        {
  2668.                          rc_grp_sep = (char *)my_realloc (rc_grp_sep, strlen(option)+1,
  2669.                                                           124, __FILE__, __LINE__ -1,
  2670.                                                           "rc_grp_sep", 0);
  2671.                          strcpy(rc_grp_sep, option);
  2672.                        }
  2673.                       else
  2674.                         if (rc_grp_sep == (char *)NULL)
  2675.                           rc_grp_sep = (char *)RC_GROUP_SEP;
  2676.                     }
  2677.                    skip_option = TRUE;
  2678.                    break;
  2679.                  case 'a':
  2680.                    if (   !rc_use_flag
  2681.                        && !is_longopt)
  2682.                      /*
  2683.                         Error, given stand-alone option actually invalid
  2684.                      */
  2685.                      opt_error = 2;
  2686.                    else
  2687.                      rc_enable_fn_flag = TRUE;
  2688.                    break;
  2689.                  case 'd':
  2690.                    if (   !rc_use_flag
  2691.                        && !is_longopt)
  2692.                      /*
  2693.                         Error, given stand-alone option actually invalid
  2694.                      */
  2695.                      opt_error = 2;
  2696.                    else
  2697.                      rc_have_today_in_list = 1;
  2698.                    break;
  2699.                  case 'e':
  2700.                  case 'E':
  2701.                    if (   !rc_use_flag
  2702.                        && !is_longopt)
  2703.                      /*
  2704.                         Error, given stand-alone option actually invalid
  2705.                      */
  2706.                      opt_error = 2;
  2707.                    else
  2708.                     {
  2709.                       if (*option == 'E')
  2710.                        {
  2711.                          rc_enable_hdl_flag = TRUE;
  2712.                          rc_enable_hda_flag = FALSE;
  2713.                        }
  2714.                       else
  2715.                        {
  2716.                          rc_enable_hdl_flag = FALSE;
  2717.                          rc_enable_hda_flag = TRUE;
  2718.                        }
  2719.                     }
  2720.                    break;
  2721.                  case 'o':
  2722.                    if (   !rc_use_flag
  2723.                        && !is_longopt)
  2724.                      /*
  2725.                         Error, given stand-alone option actually invalid
  2726.                      */
  2727.                      opt_error = 2;
  2728.                    else
  2729.                      rc_omit_date_flag = TRUE;
  2730.                    break;
  2731.                  case 'l':
  2732.                    if (   !rc_use_flag
  2733.                        && !is_longopt)
  2734.                      /*
  2735.                         Error, given stand-alone option actually invalid
  2736.                      */
  2737.                      opt_error = 2;
  2738.                    else
  2739.                      /*
  2740.                         Assume the user wants to have a list
  2741.                           of periods instead of a single period!
  2742.                      */
  2743.                      rc_period_list = TRUE;
  2744.                    break;
  2745.                  case 'k':
  2746.                    if (   !rc_use_flag
  2747.                        && !is_longopt)
  2748.                      /*
  2749.                         Error, given stand-alone option actually invalid
  2750.                      */
  2751.                      opt_error = 2;
  2752.                    else
  2753.                      rc_weekno_flag = TRUE;
  2754.                    break;
  2755.                  case 'x':
  2756.                    if (   !rc_use_flag
  2757.                        && !is_longopt)
  2758.                      /*
  2759.                         Error, given stand-alone option actually invalid
  2760.                      */
  2761.                      opt_error = 2;
  2762.                    else
  2763.                      rc_title_flag = FALSE;
  2764.                    break;
  2765.                  case 'z':
  2766.                    if (   !rc_use_flag
  2767.                        && !is_longopt)
  2768.                      /*
  2769.                         Error, given stand-alone option actually invalid
  2770.                      */
  2771.                      opt_error = 2;
  2772.                    else
  2773.                      rc_count_flag = TRUE;
  2774.                    break;
  2775.                  case 'c':
  2776.                  case 'C':
  2777.                    rc_use_flag = TRUE;
  2778.                    if (*option == 'C')
  2779.                      rc_all_dates_flag = TRUE;
  2780.                    option++;
  2781.                    if (*option == *DES_LIT)
  2782.                     {
  2783.                       rc_sort_des_flag = TRUE;
  2784.                       while (*option == *DES_LIT)
  2785.                         option++;
  2786.                     }
  2787.                    option--;
  2788.                    break;
  2789.                  case '0':
  2790.                  case '1':
  2791.                  case '2':
  2792.                  case '3':
  2793.                  case '4':
  2794.                  case '5':
  2795.                  case '6':
  2796.                  case '7':
  2797.                  case '8':
  2798.                  case '9':
  2799.                  case RC_HDY_CHAR:
  2800.                  case RC_NWD_CHAR:
  2801.                    if (   !rc_use_flag
  2802.                        && !is_longopt)
  2803.                      /*
  2804.                         Error, given stand-alone option actually invalid
  2805.                      */
  2806.                      opt_error = 2;
  2807.                    else
  2808.                     {
  2809.                       register int   act_is_leap_year=(days_of_february (act_year)==29);
  2810.                       auto     int   wmax=WEEK_MAX;
  2811.                       auto     char  dvar='\0';
  2812.                       auto     Bool  nth_day_of_year_flag=FALSE;
  2813.  
  2814.  
  2815.                       i = 0;
  2816.                       if (act_year == GREG_YEAR)
  2817.                         wmax = ((DAY_LAST + (days_of_february (GREG_YEAR) == 29)
  2818.                                - (GREG_L_DAY - GREG_F_DAY + 1)) / DAY_MAX) + 1;
  2819.                       rc_clean_flags ();
  2820.                       rc_period = 0;
  2821.                       rc_period_flag = TRUE;
  2822.                       /*
  2823.                          Before i forget... all mode specifying characters
  2824.                            ('n', 'd' or 'w') may be given in upper or lower
  2825.                            case, i.e. they are managed case insensitive!
  2826.                       */
  2827.                       /*
  2828.                          Check if @<e|`dvar'>[[-]<n>[`ww[w]']] or
  2829.                            *d|w<n>[`ww[w]'] is given
  2830.                       */
  2831.                       if (   *option == RC_HDY_CHAR
  2832.                           || *option == RC_NWD_CHAR)
  2833.                         dvar = *option;
  2834.                       else
  2835.                         /*
  2836.                            Compute period for <n>d
  2837.                         */
  2838.                         rc_period = atoi(option);
  2839.                       if (!dvar)
  2840.                        {
  2841.                          auto char  *ptr_char;
  2842.  
  2843.  
  2844.                          /*
  2845.                             Check if <n>+ is given
  2846.                          */
  2847.                          rc_forwards_flag = (Bool)(strchr(option, *ASC_LIT) != (char *)NULL);
  2848.                          /*
  2849.                             Check if  <n>- is given
  2850.                          */
  2851.                          rc_backwards_flag = (Bool)(strchr(option, *DES_LIT) != (char *)NULL);
  2852.                          /*
  2853.                             Check if <n>w is given
  2854.                          */
  2855.                          ptr_char = strrchr(option, 'w');
  2856.                          if (ptr_char == (char *)NULL)
  2857.                            ptr_char = strrchr(option, 'W');
  2858.                          if (ptr_char != (char *)NULL)
  2859.                           {
  2860.                             ptr_char++;
  2861.                             if (!*ptr_char)
  2862.                               rc_week_year_flag = TRUE;
  2863.                           }
  2864.                          /*
  2865.                             Check if <n>d is given
  2866.                          */
  2867.                          ptr_char = strrchr(option, 'd');
  2868.                          if (ptr_char == (char *)NULL)
  2869.                            ptr_char = strrchr(option, 'D');
  2870.                          if (ptr_char != (char *)NULL)
  2871.                           {
  2872.                             ptr_char++;
  2873.                             if (!*ptr_char)
  2874.                               nth_day_of_year_flag = TRUE;
  2875.                           }
  2876.                          i = (int)rc_forwards_flag + rc_backwards_flag
  2877.                              + rc_week_year_flag + nth_day_of_year_flag;
  2878.                        }
  2879.                       /*
  2880.                          Compute period for <n>d
  2881.                       */
  2882.                       if (rc_period == 999)
  2883.                         rc_period = DAY_LAST + act_is_leap_year;
  2884.                       if (   !dvar
  2885.                           && (   i > 1
  2886.                               || (   (rc_period > DAY_LAST+act_is_leap_year)
  2887.                                   && (   rc_forwards_flag
  2888.                                       || rc_backwards_flag
  2889.                                       || nth_day_of_year_flag))
  2890.                               || (   rc_week_year_flag
  2891.                                   && (rc_period > wmax+1)
  2892.                                   && (rc_period != 99))))
  2893.                         /*
  2894.                            Error, illegal warning period modifier given
  2895.                         */
  2896.                         opt_error = 5;
  2897.                       else
  2898.                        {
  2899.                          /*
  2900.                             Found one of these warning period modifiers:
  2901.                               @<e|`dvar'>[[-]<n>[`ww[w]']]
  2902.                               *d|w<n>[`ww[w]']
  2903.                               `mmdd'
  2904.                               `mmww[w]'<n>
  2905.                          */
  2906.                          if (   !rc_week_year_flag
  2907.                              && !rc_forwards_flag
  2908.                              && !rc_backwards_flag)
  2909.                           {
  2910.                             auto int   y=act_year;
  2911.                             auto int   n;
  2912.                             auto char  hc;
  2913.                             auto Bool  is_weekday_mode;
  2914.  
  2915.  
  2916.                             if (!nth_day_of_year_flag)
  2917.                              {
  2918.                                sprintf(s2, "%0*d%s", len_year_max, y, option);
  2919.                                /*
  2920.                                   rc_get_date() arguments `wmax', `hc' and `i' are dummys
  2921.                                     only and must be given.  they are not respected!
  2922.                                */
  2923.                                (void)rc_get_date (s2, &is_weekday_mode, &day, &month, &y, &n, &wmax,
  2924.                                                   &hc, &i, &i, &hc, 0, &hc, FALSE);
  2925.                                if (y != -1)
  2926.                                 {
  2927.                                   if (!dvar)
  2928.                                    {
  2929.                                      /*
  2930.                                         `mmww[w]'<n> or `mmdd' given
  2931.                                      */
  2932.                                      if (!month)
  2933.                                        month = act_month;
  2934.                                      if (   month < MONTH_MIN
  2935.                                          || month > MONTH_MAX)
  2936.                                        /*
  2937.                                           Error, invalid month given
  2938.                                        */
  2939.                                        opt_error = 5;
  2940.                                      else
  2941.                                       {
  2942.                                         i = dvec[month-1];
  2943.                                         if (month == 2)
  2944.                                           i += act_is_leap_year;
  2945.                                         if (is_weekday_mode)
  2946.                                          {
  2947.                                            /*
  2948.                                               `mmww[w]'<n> given
  2949.                                            */
  2950.                                            if (n == 9)
  2951.                                              day = eval_holiday (i, month, act_year, day, FALSE);
  2952.                                            else
  2953.                                             {
  2954.                                               day = eval_holiday (DAY_MIN, month, act_year, day, TRUE);
  2955.                                               day += (DAY_MAX * (n - 1));
  2956.                                               if (day > i)
  2957.                                                 /*
  2958.                                                    Error, month contains no such "n'th weekday of month"
  2959.                                                 */
  2960.                                                 opt_error = 5;
  2961.                                               else
  2962.                                                {
  2963.                                                  /*
  2964.                                                     Now check if given date is valid
  2965.                                                  */
  2966.                                                  if (   !day
  2967.                                                      || !valid_date (day, month, act_year))
  2968.                                                    /*
  2969.                                                       Error, invalid date given
  2970.                                                    */
  2971.                                                    opt_error = 5;
  2972.                                                }
  2973.                                             }
  2974.                                          }
  2975.                                         else
  2976.                                          {
  2977.                                            /*
  2978.                                               `mmdd' given
  2979.                                            */
  2980.                                            if (day == 99)
  2981.                                              day = i;
  2982.                                            if (!day)
  2983.                                              day = act_day;
  2984.                                            if (   day < DAY_MIN
  2985.                                                || day > i)
  2986.                                              /*
  2987.                                                 Error, invalid day given
  2988.                                              */
  2989.                                              opt_error = 5;
  2990.                                          }
  2991.                                       }
  2992.                                    }
  2993.                                   else
  2994.                                     if (   !day
  2995.                                         || !month)
  2996.                                       /*
  2997.                                          Error, either invalid date variable
  2998.                                            or invalid mode specifier given (not d|w)
  2999.                                       */
  3000.                                       opt_error = 5;
  3001.                                   if (!opt_error)
  3002.                                     rc_period = day_of_year (day, month, act_year);
  3003.                                 }
  3004.                                else
  3005.                                  /*
  3006.                                     Error, invalid date given
  3007.                                  */
  3008.                                  opt_error = 5;
  3009.                              }
  3010.                             else
  3011.                               if (!rc_period)
  3012.                                 /*
  3013.                                    Error, zero date is invalid
  3014.                                 */
  3015.                                 opt_error = 5;
  3016.                             if (!opt_error)
  3017.                              {
  3018.                                i = day_of_year (act_day, act_month, act_year);
  3019.                                if (rc_period >= i)
  3020.                                 {
  3021.                                   rc_forwards_flag = TRUE;
  3022.                                   rc_period -= i;
  3023.                                 }
  3024.                                else
  3025.                                 {
  3026.                                   rc_backwards_flag = TRUE;
  3027.                                   rc_period = i - rc_period;
  3028.                                 }
  3029.                              }
  3030.                           }
  3031.                          else
  3032.                           {
  3033.                             /*
  3034.                                <n>w|+|- given
  3035.                             */
  3036.                             i = 0;
  3037.                             while (isdigit(*option))
  3038.                              {
  3039.                                i++;
  3040.                                option++;
  3041.                              }
  3042.                             option--;
  3043.                             if (   !rc_period
  3044.                                 && !rc_week_year_flag)
  3045.                               /*
  3046.                                  Error, zero lenght date of warning period given
  3047.                               */
  3048.                               opt_error = 5;
  3049.                             else
  3050.                               further_check = TRUE;
  3051.                           }
  3052.                        }
  3053.                     }
  3054.                    skip_option = TRUE;
  3055.                    break;
  3056.                  case 't':
  3057.                  case 'T':
  3058.                    if (   !rc_use_flag
  3059.                        && !is_longopt)
  3060.                      /*
  3061.                         Error, given stand-alone option actually invalid
  3062.                      */
  3063.                      opt_error = 2;
  3064.                    else
  3065.                     {
  3066.                       rc_clean_flags ();
  3067.                       rc_tomorrow_flag = TRUE;
  3068.                       if (*option == 'T')
  3069.                         rc_all_dates_flag = TRUE;
  3070.                       option++;
  3071.                       if (*option)
  3072.                         /*
  3073.                            Error, invalid option modifier given
  3074.                         */
  3075.                         opt_error = 2;
  3076.                       skip_option = TRUE;
  3077.                     }
  3078.                    break;
  3079.                  case 'w':
  3080.                  case 'W':
  3081.                    if (   !rc_use_flag
  3082.                        && !is_longopt)
  3083.                      /*
  3084.                         Error, given stand-alone option actually invalid
  3085.                      */
  3086.                      opt_error = 2;
  3087.                    else
  3088.                     {
  3089.                       rc_clean_flags ();
  3090.                       rc_week_flag = TRUE;
  3091.                       if (*option == 'W')
  3092.                         rc_all_dates_flag = TRUE;
  3093.                       further_check = TRUE;
  3094.                     }
  3095.                    break;
  3096.                  case 'm':
  3097.                  case 'M':
  3098. #  ifdef GCAL_EMAIL
  3099.                    if (   (*option == 'm')
  3100.                        && *(option+1)
  3101.                        && (*(option+1) != *ASC_LIT)
  3102.                        && (*(option+1) != *DES_LIT))
  3103.                     {
  3104.                       option++;
  3105.                       email_adr = (char *)my_realloc (email_adr, strlen(option)+1,
  3106.                                                       124, __FILE__, __LINE__ -1,
  3107.                                                       "email_adr", 0);
  3108.                       strcpy(email_adr, option);
  3109.                       skip_option = TRUE;
  3110.                     }
  3111.                    else
  3112. #  endif
  3113.                      if (   !rc_use_flag
  3114.                          && !is_longopt)
  3115. #  ifdef GCAL_EMAIL
  3116.                        /*
  3117.                           Error, option character is not trailed by an argument
  3118.                        */
  3119.                        opt_error = 4;
  3120. #  else /* !GCAL_EMAIL */
  3121.                        /*
  3122.                           Error, given stand-alone option actually invalid
  3123.                        */
  3124.                        opt_error = 2;
  3125. #  endif /* !GCAL_EMAIL */
  3126.                      else
  3127.                       {
  3128.                         rc_clean_flags ();
  3129.                         rc_month_flag = TRUE;
  3130.                         if (*option == 'M')
  3131.                           rc_all_dates_flag = TRUE;
  3132.                         further_check = TRUE;
  3133.                       }
  3134.                    break;
  3135.                  case 'y':
  3136.                  case 'Y':
  3137.                    if (   !rc_use_flag
  3138.                          && !is_longopt)
  3139.                      /*
  3140.                         Error, given stand-alone option actually invalid
  3141.                      */
  3142.                      opt_error = 2;
  3143.                    else
  3144.                     {
  3145.                       rc_clean_flags ();
  3146.                       rc_year_flag = TRUE;
  3147.                       if (*option == 'Y')
  3148.                         rc_all_dates_flag = TRUE;
  3149.                       further_check = TRUE;
  3150.                     }
  3151.                    break;
  3152. #else  /* !USE_RC */
  3153.                  case 'm':
  3154. #  ifdef GCAL_EMAIL
  3155.                    option++;
  3156.                    if (*option)
  3157.                     {
  3158.                       email_adr = (char *)my_realloc (email_adr, strlen(option)+1,
  3159.                                                       124, __FILE__, __LINE__ -1,
  3160.                                                       "email_adr", 0);
  3161.                       strcpy(email_adr, option);
  3162.                       skip_option = TRUE;
  3163.                     }
  3164.                    else
  3165. #  endif
  3166.                      /*
  3167.                         Error, option character is not trailed by an argument
  3168.                      */
  3169.                      opt_error = 4;
  3170.                    break;
  3171. #endif /* !USE_RC */
  3172.                  default:
  3173.                    /*
  3174.                       Error, any unmanaged options are always invalid
  3175.                    */
  3176.                    opt_error = 2;
  3177.                }
  3178. #if USE_RC
  3179.             if (   further_check
  3180.                 && !opt_error)
  3181.              {
  3182.                option++;
  3183.                if (*option)
  3184.                 {
  3185.                   rc_week_year_flag = (Bool)(tolower(*option) == 'w');
  3186.                   rc_forwards_flag = (Bool)(*option == *ASC_LIT);
  3187.                   rc_backwards_flag = (Bool)(*option == *DES_LIT);
  3188.                   option++;
  3189.                   if (   *option
  3190.                       || (   !rc_week_year_flag
  3191.                           && !rc_forwards_flag
  3192.                           && !rc_backwards_flag))
  3193.                     /*
  3194.                        Error, either argument is trailed by an illegal character
  3195.                          or no mode specifying character (w|+|-) is given
  3196.                     */
  3197.                     opt_error = 2;
  3198.                 }
  3199.                skip_option = TRUE;
  3200.              }
  3201. #endif /* USE_RC */
  3202.             if (opt_error)
  3203.              {
  3204.                switch (opt_error)
  3205.                 {
  3206. #if USE_GER
  3207.                   case 1:
  3208.                     sprintf(s, "%s: Option `%s' ist nicht eindeutig",
  3209.                             prgr_name, *argv);
  3210.                     break;
  3211.                   case 2:
  3212.                     if (is_longopt)
  3213.                       sprintf(s, "%s: Option ist unbekannt `%s'",
  3214.                               prgr_name, *argv);
  3215.                     else
  3216.                       sprintf(s, "%s: Option ist ung"UE"ltig -- %s",
  3217.                               prgr_name, *argv+1);
  3218.                     break;
  3219.                   case 3:
  3220.                     sprintf(s, "%s: Option `%s' erlaubt kein Argument",
  3221.                             prgr_name, *argv);
  3222.                     break;
  3223.                   case 4:
  3224.                     if (is_longopt)
  3225.                       sprintf(s, "%s: Option `%s' ben"OE"tigt ein Argument",
  3226.                               prgr_name, *argv);
  3227.                     else
  3228.                       sprintf(s, "%s: Option ben"OE"tigt ein Argument -- %s",
  3229.                               prgr_name, *argv+1);
  3230.                     break;
  3231.                   case 5:
  3232.                     sprintf(s, "%s: Option mit unzul"AE"ssigem Argument -- %s",
  3233.                             prgr_name, *argv);
  3234.                     break;
  3235.                   case 6:
  3236.                     sprintf(s, "%s: Option mit nicht eindeutigem Argument -- %s",
  3237.                             prgr_name, *argv);
  3238. #else /* !USE_GER */
  3239.                   case 1:
  3240.                     sprintf(s, "%s: option `%s' is ambiguous",
  3241.                             prgr_name, *argv);
  3242.                     break;
  3243.                   case 2:
  3244.                     if (is_longopt)
  3245.                       sprintf(s, "%s: unrecognized option `%s'",
  3246.                               prgr_name, *argv);
  3247.                     else
  3248.                       sprintf(s, "%s: invalid option -- %s",
  3249.                               prgr_name, *argv+1);
  3250.                     break;
  3251.                   case 3:
  3252.                     sprintf(s, "%s: option `%s' doesn't allow an argument",
  3253.                             prgr_name, *argv);
  3254.                     break;
  3255.                   case 4:
  3256.                     if (is_longopt)
  3257.                       sprintf(s, "%s: option `%s' requires an argument",
  3258.                               prgr_name, *argv);
  3259.                     else
  3260.                       sprintf(s, "%s: option requires an argument -- %s",
  3261.                               prgr_name, *argv+1);
  3262.                     break;
  3263.                   case 5:
  3264.                     sprintf(s, "%s: option with invalid argument -- %s",
  3265.                             prgr_name, *argv);
  3266.                     break;
  3267.                   case 6:
  3268.                     sprintf(s, "%s: option with ambiguous argument -- %s",
  3269.                             prgr_name, *argv);
  3270. #endif /* !USE_GER */
  3271.                     break;
  3272.                   default:
  3273.                     my_error (opt_error, "", 0, "", 0);   /* This case must be an Internal error */
  3274.                 }
  3275.                fprintf(stderr, "%s\n%s\n", s, usage_msg ());
  3276.                put_longopt_description (stderr);
  3277.                S_NEWLINE(stderr);
  3278.                exit(126);
  3279.              }
  3280.             if (skip_option)
  3281.              {
  3282.                while (*option)
  3283.                  option++;
  3284.                option--;
  3285.              }
  3286.           }
  3287.          argc--;
  3288.        }
  3289.       else
  3290.        {
  3291. #if USE_RC
  3292.          /*
  3293.             If actual date modifier %... is given, skip/ignore complete option
  3294.               because it's already managed by the main() function
  3295.          */
  3296.          if (**argv == RC_ADATE_CHAR)
  3297.            argc--;
  3298.          else
  3299. #endif
  3300.            break;
  3301.        }
  3302.     }
  3303.    if (   help_flag
  3304.        || license_flag
  3305.        || version_flag)
  3306.     {
  3307. #if USE_PAGER
  3308.       /*
  3309.          No program output yet and output goes to a tty:
  3310.            set the standard stream buffers to unbuffered mode,
  3311.            then get actual settings of the tty (needed if paging is wanted)
  3312.       */
  3313.       if (   is_tty1
  3314.           && is_tty2
  3315. #  ifdef GCAL_EPAGER
  3316.           && (ext_pager == (char *)NULL)
  3317. #  endif
  3318.          )
  3319.        {
  3320.          setbuf(stdout, (char *)NULL);
  3321.          setbuf(stdin, (char *)NULL);
  3322.          get_tty_scr_size (&tty_rows, &tty_cols);
  3323.        }
  3324. #endif /* USE_PAGER */
  3325.       /*
  3326.          Get the highlighting sequences of the terminal
  3327.       */
  3328.       get_tty_hls (hl_seq);
  3329. #ifdef GCAL_EPAGER
  3330.       if (   is_tty1
  3331.           && is_tty2
  3332.           && pager_flag
  3333.           && (ext_pager != (char *)NULL))
  3334.        {
  3335.          child_pid = fork();
  3336.          switch (child_pid)
  3337.           {
  3338.             case -1:
  3339.               /*
  3340.                  Error, fork() fails
  3341.               */
  3342.               my_error (110, __FILE__, __LINE__ -7, "fork()", 0);
  3343.             case 0:
  3344.               /*
  3345.                  Child process (read from pipe):
  3346.                    connect pipe-stdin to sys-stdin in a safe way
  3347.                    and launch external pager
  3348.               */
  3349.               close(pipe_fd[1]);
  3350.               if (pipe_fd[0])
  3351.                {
  3352.                  close(0);
  3353.                  dup(pipe_fd[0]);
  3354.                  close(pipe_fd[0]);
  3355.                }
  3356.               execlp(ext_pager, ext_pager, (char *)NULL);
  3357.               /*
  3358.                  Error, execlp() fails (this line should never be executed)
  3359.               */
  3360.               sprintf(s, "execlp(%s)", ext_pager);
  3361.               my_error (110, __FILE__, __LINE__ -5, s, 0);
  3362.             default:
  3363.               /*
  3364.                  Parent process (write to pipe):
  3365.                    connect pipe-stdout to sys-stdout in a safe way
  3366.                    and initiate action
  3367.               */
  3368.               close(pipe_fd[0]);
  3369.               if (pipe_fd[1] != 1)
  3370.                {
  3371.                  close(1);
  3372.                  if (!dup(pipe_fd[1]))
  3373.                   {
  3374.                     dup(pipe_fd[1]);
  3375.                     close(0);
  3376.                   }
  3377.                  close(pipe_fd[1]);
  3378.                }
  3379.           }
  3380.        }
  3381. #endif /* GCAL_EPAGER */
  3382.       if (help_flag)
  3383.        {
  3384.          if (ext_help_flag)
  3385.            /*
  3386.               Extended help pages (--long-help[=ARG] or -hh or -?? or -h? or -?h)
  3387.            */
  3388.            my_extended_help (stdout, lopt_help);
  3389.          else
  3390.            /*
  3391.               Basic help page (--help or -h or -?)
  3392.            */
  3393.            my_basic_help (stdout);
  3394.        }
  3395.       else
  3396.        {
  3397.          /*
  3398.             Store program name and some information to global text buffer `s2'
  3399.          */
  3400.          strncpy(s, rcsid+11, 25);
  3401.          s[25] = '\0';
  3402.          sprintf(s2, "%s%s", prgr_name, s);
  3403.          if (license_flag)
  3404.            /*
  3405.               License text (--license or -L)
  3406.            */
  3407.            my_license (stdout, s2);
  3408.          else
  3409.            if (version_flag)
  3410.              /*
  3411.                 Version text (--version or -V)
  3412.              */
  3413.              my_version (stdout, s2);
  3414.        }
  3415. #ifdef GCAL_EPAGER
  3416.       if (   is_tty1
  3417.           && is_tty2
  3418.           && pager_flag
  3419.           && (ext_pager != (char *)NULL))
  3420.        {
  3421.          /*
  3422.             We work unbuffered in this case so we have to flush stdout buffer
  3423.               for showing all contents of it
  3424.          */
  3425.          fflush(stdout);
  3426.          /*
  3427.             And reconnect the sys-stdin/sys-stdout file descriptors
  3428.          */
  3429.          close(0);
  3430.          dup(sys_fd[0]);
  3431.          close(1);
  3432.          dup(sys_fd[1]);
  3433.          /*
  3434.             And wait until child has performed all action
  3435.          */
  3436.          while (wait((pid_t *)NULL) != child_pid)
  3437.            ;
  3438.          /*
  3439.             Reset SIGPIPE signal
  3440.          */
  3441.          signal(SIGPIPE, SIG_DFL);
  3442.        }
  3443. #endif /* GCAL_EPAGER */
  3444.       exit(EXIT_STAT_HLP);
  3445.     }
  3446.    month = 0;
  3447.    if (argc > 1)
  3448.     {
  3449.       auto     Bool  is_list=FALSE;
  3450.       auto     Bool  is_range=FALSE;
  3451.       auto     Bool  month_set=FALSE;
  3452.       auto     Bool  year_sep_found=FALSE;
  3453.  
  3454.  
  3455.       for ( ; argc > 1 ; argc--, argv++)
  3456.        {
  3457.          if (!month)
  3458.           {
  3459.             option = *argv;
  3460.             if (*option == *MONTH3_LIT)
  3461.               break;
  3462.             else
  3463.               while (*option)
  3464.                {
  3465.                  if (   *option == *MLIST_SEP
  3466.                      || *option == *YLIST_SEP)
  3467.                    is_list = TRUE;
  3468.                  else
  3469.                    if (   *option == *MRANGE_SEP
  3470.                        || *option == *YRANGE_SEP)
  3471.                      is_range = TRUE;
  3472.                    else
  3473.                      if (*option == *YEAR_SEP)
  3474.                        year_sep_found = TRUE;
  3475.                      else
  3476.                        if (*option == *FYEAR_SEP)
  3477.                          is_fiscal_year = TRUE;
  3478.                  option++;
  3479.                }
  3480.             option = *argv;
  3481.             if (   !is_list
  3482.                 && !is_range
  3483.                 && !year_sep_found
  3484.                 && !is_fiscal_year
  3485.                 && !my_atoi (option))
  3486.              {
  3487.                month = compare_d_m_name (option, MOnth);
  3488.                if (month)
  3489.                 {
  3490.                   month_set = TRUE;
  3491.                   continue;
  3492.                 }
  3493.              }
  3494.           }
  3495.          if (!month)
  3496.           {
  3497.             build_month_list (argv);
  3498.             if (!*month_list.month)
  3499.               month = atoi(*argv);
  3500.             else
  3501.               month = *month_list.month;
  3502.             if (   month < MONTH_MIN
  3503.                 || month > MONTH_MAX)
  3504.              {
  3505.                if (!is_fiscal_year)
  3506.                  year = month;
  3507.                month = 0;
  3508.                break;
  3509.              }
  3510.           }
  3511.          else
  3512.            if (!year)
  3513.             {
  3514.               if (   *month_list.year
  3515.                   && (   is_list
  3516.                       || is_range))
  3517.                 year = *month_list.year;
  3518.               else
  3519.                 year = my_atoi (*argv);
  3520.             }
  3521.        }
  3522.       /*
  3523.          "." or ".." or ".+" or ".-" argument found:
  3524.            3 month mode wanted
  3525.       */
  3526.       if (*option == *MONTH3_LIT)
  3527.        {
  3528.          register int  len=(int)strlen(option);
  3529.  
  3530.  
  3531.          if (len <= 2)
  3532.           {
  3533.             if (*(option + 1) == *MONTH3_LIT)
  3534.               is_3month_mode2 = TRUE;
  3535.             else
  3536.               is_3month_mode = TRUE;
  3537.             is_fiscal_year = TRUE;
  3538.             year_flag = FALSE;
  3539.             month = act_month;
  3540.             /*
  3541.                Check if an explicit year trails the 3 month mode command
  3542.             */
  3543.             if (argc > 2)
  3544.              {
  3545.                argv++;
  3546.                year = atoi(*argv);
  3547.                if (!year)
  3548.                  year = act_year;
  3549.              }
  3550.             else
  3551.               year = act_year;
  3552.             if (is_3month_mode)
  3553.              {
  3554.                /*
  3555.                   Either "." or ".+" or ".-" 3 month mode command found
  3556.                */
  3557.                if (!*(option + 1))
  3558.                 {
  3559.                   /*
  3560.                      "." 3 month mode command found
  3561.                   */
  3562.                   month--;
  3563.                   if (!month)
  3564.                    {
  3565.                      month = MONTH_MAX;
  3566.                      year--;
  3567.                    }
  3568.                 }
  3569.                else
  3570.                  if (*(option + 1) == *DES_LIT)
  3571.                   {
  3572.                     /*
  3573.                        ".-" 3 month mode command found
  3574.                     */
  3575.                     month -= 2;
  3576.                     if (month < MONTH_MIN)
  3577.                      {
  3578.                        month = MONTH_MAX + month;
  3579.                        year--;
  3580.                      }
  3581.                   }
  3582.                  else
  3583.                    if (*(option + 1) == *ASC_LIT)
  3584.                      /*
  3585.                         ".+" 3 month mode command found
  3586.                      */
  3587.                      ;   /* Void, nothing to do! */
  3588.                    else
  3589.                     {
  3590.                       /*
  3591.                          Error, invalid modifier trails the dot character ->
  3592.                            print default month calendar only
  3593.                       */
  3594.                       is_fiscal_year = FALSE;
  3595.                       year = act_year;
  3596.                       month = act_month;
  3597.                     }
  3598.                if (year < YEAR_MIN)
  3599.                 {
  3600.                   year = YEAR_MIN;
  3601.                   month = act_month;
  3602.                 }
  3603.              }
  3604.             else
  3605.               /*
  3606.                  ".." 3 month mode command found
  3607.               */
  3608.               month = ((month + 1) - ((month - 1) % 3)) - 1;
  3609.           }
  3610.        }
  3611.       else
  3612.         if (   month
  3613.             && !year
  3614.             && !month_set
  3615.             && !*month_list.month
  3616.             && !is_fiscal_year)
  3617.          {
  3618.            year = month;
  3619.            month = 0;
  3620.          }
  3621.     }
  3622. }
  3623.  
  3624.  
  3625.  
  3626. #ifdef ANSI_PROTO
  3627. LOCAL void
  3628. build_month_list (char *argv[])
  3629. #else /* !ANSI_PROTO */
  3630.    LOCAL void
  3631. build_month_list (argv)
  3632.    char *argv[];
  3633. #endif /* !ANSI_PROTO */
  3634. /*
  3635.    If more than a single month/year is wanted, fill the global
  3636.      data structure `month_list'; used in print_calendar();
  3637.      according the values found in the command line
  3638. */
  3639. {
  3640.    register       int    i;
  3641.    register       int    j;
  3642.    auto     const char  *option;
  3643.    auto           Bool   is_list=FALSE;
  3644.    auto           Bool   is_range=FALSE;
  3645.    auto           Bool   year_sep_found=FALSE;
  3646.    auto           Bool   buf_is_ext_year;
  3647.  
  3648.  
  3649.    option = *argv;
  3650.    for ( ; *option && !is_list && !is_range ; option++)
  3651.      if (   *option == *MLIST_SEP
  3652.          || *option == *YLIST_SEP)
  3653.       {
  3654.         is_list = TRUE;
  3655.         if (*option == *YLIST_SEP)
  3656.           is_ext_list=is_ext_year = TRUE;
  3657.       }
  3658.      else
  3659.        if (   *option == *MRANGE_SEP
  3660.            || *option == *YRANGE_SEP)
  3661.         {
  3662.           is_range = TRUE;
  3663.           if (*option == *YRANGE_SEP)
  3664.             is_ext_range=is_ext_year = TRUE;
  3665.         }
  3666.        else
  3667.          if (*option == *YEAR_SEP)
  3668.            year_sep_found = TRUE;
  3669.    buf_is_ext_year = is_ext_year;
  3670.    if (   year_sep_found
  3671.        || (   is_fiscal_year
  3672.            && (   is_ext_list
  3673.                || is_ext_year
  3674.                || (   !is_list
  3675.                    && !is_range)))
  3676.        || (   !is_fiscal_year
  3677.            && (   is_list
  3678.                || is_range)))
  3679.     {
  3680.       i = 0;
  3681.       option = *argv;
  3682.       while (   *option
  3683.              && (i < MONTH_MAX))
  3684.        {
  3685.          year_sep_found = FALSE;
  3686.          j = 0;
  3687.          while (   *option
  3688.                 && !year_sep_found
  3689.                 && (   (   !is_list
  3690.                         && !is_range)
  3691.                     || (   (   is_list
  3692.                             && (   (*option != *MLIST_SEP)
  3693.                                 && (*option != *YLIST_SEP)))
  3694.                         || (   is_range
  3695.                             && (   (*option != *MRANGE_SEP)
  3696.                                 && (*option != *YRANGE_SEP))))))
  3697.           {
  3698.             year_sep_found = (Bool)(   *option == *YEAR_SEP
  3699.                                     || *option == *FYEAR_SEP);
  3700.             s[j++] = *option++;
  3701.           }
  3702.          if (year_sep_found)
  3703.            s[j-1] = '\0';
  3704.          else
  3705.            s[j] = '\0';
  3706.          if (!*s)
  3707.           {
  3708.             if (is_fiscal_year)
  3709.              {
  3710.                j = atoi(option);
  3711.                if (j)
  3712.                 {
  3713.                   is_ext_year = FALSE;
  3714.                   month_list.month[i++] = act_month;
  3715.                 }
  3716.              }
  3717.             else
  3718.              {
  3719.                j = 0;
  3720.                while (*option)
  3721.                  option++;
  3722.              }
  3723.           }
  3724.          else
  3725.            j = my_atoi (s);
  3726.          if (is_ext_year)
  3727.           {
  3728.             if (is_fiscal_year)
  3729.              {
  3730.                if (   (j >= MONTH_MIN)
  3731.                    && (j <= MONTH_MAX))
  3732.                  month_list.month[i++] = j;
  3733.                else
  3734.                 {
  3735.                   /*
  3736.                      Argument a valid month name?
  3737.                   */
  3738.                   j = compare_d_m_name (s, MOnth);
  3739.                   if (j)
  3740.                     month_list.month[i++] = j;
  3741.                   else
  3742.                     /*
  3743.                        At end of argument?
  3744.                     */
  3745.                     if (!*option)
  3746.                      {
  3747.                        if (   is_ext_list
  3748.                            || is_ext_range)
  3749.                         {
  3750.                           if (!is_ext_list)
  3751.                             month_list.month[i] = month_list.month[i-1];
  3752.                           else
  3753.                             month_list.month[i] = MONTH_MIN;
  3754.                           j = my_atoi (s);
  3755.                           if (j)
  3756.                             month_list.year[i++] = j;
  3757.                           else
  3758.                             month_list.month[i] = 0;
  3759.                         }
  3760.                      }
  3761.                     else
  3762.                       /*
  3763.                          Not at end of argument:
  3764.                            fiscal year list wanted and standard year given
  3765.                       */
  3766.                       if (!year_sep_found)
  3767.                        {
  3768.                          j = my_atoi (s);
  3769.                          if (j)
  3770.                            month_list.month [i++] = j;
  3771.                          /*
  3772.                             Otherwise ignore given argument
  3773.                          */
  3774.                        }
  3775.                       else
  3776.                         year_sep_found = FALSE;
  3777.                 }
  3778.              }
  3779.             else
  3780.              {
  3781.                if (year_sep_found)
  3782.                 {
  3783.                   /*
  3784.                      Error, extended year list/range given like
  3785.                        5/1999;may/7777... or 5/1999+may/7777
  3786.                        --> respect the year part of date only
  3787.                   */
  3788.                   j = 0;
  3789.                   while (   *option
  3790.                          && (   (   is_list
  3791.                                  && (*option != *YLIST_SEP))
  3792.                              || (   is_range
  3793.                                  && (*option != *YRANGE_SEP))))
  3794.                     s[j++] = *option++;
  3795.                   s[j] = '\0';
  3796.                   j = my_atoi (s);
  3797.                 }
  3798.                if (j)
  3799.                  month_list.month[i++] = j;
  3800.                else
  3801.                  if (is_list)
  3802.                    month_list.month[i++] = act_year;
  3803.              }
  3804.             if (year_sep_found)
  3805.              {
  3806.                while (   *option == *YEAR_SEP
  3807.                       || *option == *FYEAR_SEP)
  3808.                  option++;
  3809.                if (!is_fiscal_year)
  3810.                 {
  3811.                   year_sep_found = FALSE;
  3812.                   while (   *option
  3813.                          && (   (   is_list
  3814.                                  && (*option != *YLIST_SEP))
  3815.                              || (   is_range
  3816.                                  && (*option != *YRANGE_SEP))))
  3817.                     option++;
  3818.                 }
  3819.              }
  3820.           }
  3821.          else
  3822.            if (*s)
  3823.             {
  3824.               if (   (j >= MONTH_MIN)
  3825.                   && (j <= MONTH_MAX))
  3826.                 month_list.month[i++] = j;
  3827.               else
  3828.                {
  3829.                  j = compare_d_m_name (s, MOnth);
  3830.                  if (j)
  3831.                    month_list.month[i++] = j;
  3832.                }
  3833.             }
  3834.          if (year_sep_found)
  3835.           {
  3836.             if (j)
  3837.              {
  3838.                j = 0;
  3839.                while (   *option == *YEAR_SEP
  3840.                       || *option == *FYEAR_SEP)
  3841.                  option++;
  3842.                if (   !is_list
  3843.                    && !is_range)
  3844.                  while (*option)
  3845.                    s[j++] = *option++;
  3846.                else
  3847.                  if (   is_fiscal_year
  3848.                      && (   is_ext_list
  3849.                          || is_ext_range))
  3850.                    while (   *option
  3851.                           && (   (   is_list
  3852.                                   && (*option != *YLIST_SEP))
  3853.                               || (   is_range
  3854.                                   && (*option != *YRANGE_SEP))))
  3855.                      s[j++] = *option++;
  3856.                  else
  3857.                    while (   *option
  3858.                           && (   (   is_list
  3859.                                   && (*option != *MLIST_SEP))
  3860.                               || (   is_range
  3861.                                   && (*option != *MRANGE_SEP))))
  3862.                      s[j++] = *option++;
  3863.                s[j] = '\0';
  3864.                j = my_atoi (s);
  3865.                if (j)
  3866.                 {
  3867.                   month_list.year[i-1] = j;
  3868.                   if (   is_list
  3869.                       && !is_ext_range)
  3870.                     is_ext_list = TRUE;
  3871.                   else
  3872.                     if (   is_range
  3873.                         && !is_ext_list)
  3874.                       is_ext_range = TRUE;
  3875.                 }
  3876.                else
  3877.                  if (is_fiscal_year)
  3878.                    month_list.year[i-1] = act_year;
  3879.              }
  3880.             else
  3881.              {
  3882.                if (is_fiscal_year)
  3883.                  while (   *option
  3884.                         && (   (   is_list
  3885.                                 && (*option != *YLIST_SEP))
  3886.                             || (   is_range
  3887.                                 && (*option != *YRANGE_SEP))))
  3888.                    option++;
  3889.                else
  3890.                  while (   *option
  3891.                         && (   (   is_list
  3892.                                 && (*option != *MLIST_SEP))
  3893.                             || (   is_range
  3894.                                 && (*option != *MRANGE_SEP))))
  3895.                    option++;
  3896.              }
  3897.           }
  3898.          while (   *option == *MLIST_SEP
  3899.                 || *option == *MRANGE_SEP
  3900.                 || *option == *YLIST_SEP
  3901.                 || *option == *YRANGE_SEP)
  3902.            option++;
  3903.          /*
  3904.             Fiscal year list/range wanted and year list/range incomplete
  3905.               --> avoid error
  3906.          */
  3907.          if (   i
  3908.              && is_fiscal_year
  3909.              && !month_list.year[i-1])
  3910.           {
  3911.             month_list.year[i-1] = month_list.month[i-1];
  3912.             month_list.month[i-1] = MONTH_MIN;
  3913.           }
  3914.          is_ext_year = buf_is_ext_year;
  3915.        }
  3916.       if (   is_range
  3917.           && !is_ext_range)
  3918.        {
  3919.          register int  k;
  3920.  
  3921.  
  3922.          /*
  3923.             Fiscal year wanted and only month range given
  3924.               --> avoid error
  3925.          */
  3926.          if (is_fiscal_year)
  3927.            is_ext_year = TRUE;
  3928.          else
  3929.           {
  3930.             /*
  3931.                Ok, compute month range and place it in list
  3932.             */
  3933.             j = *month_list.month;
  3934.             k = month_list.month[1];
  3935.             i = 0;
  3936.             while (month_list.month[i])
  3937.               month_list.month[i++] = 0;
  3938.             if (   !j
  3939.                 && !k)
  3940.               *month_list.month = act_month;
  3941.             else
  3942.              {
  3943.                if (!j)
  3944.                  j = MONTH_MIN;
  3945.                if (!k)
  3946.                  k = MONTH_MAX;
  3947.                i = 0;
  3948.                if (j > k)
  3949.                  for ( ; j >= k ; i++, j--)
  3950.                    month_list.month[i] = j;
  3951.                else
  3952.                  for ( ; j <= k ; i++, j++)
  3953.                    month_list.month[i] = j;
  3954.              }
  3955.           }
  3956.        }
  3957.       /*
  3958.          Fiscal-/ standard year wanted and invalid range
  3959.            --> avoid error
  3960.       */
  3961.       if (   is_ext_range
  3962.           && month_list.month[2])
  3963.         month_list.month[1] = 0;
  3964.       /*
  3965.          Standard year wanted and year list/range incomplete
  3966.            --> avoid error
  3967.       */
  3968.       if (   !month_list.month[1]
  3969.           && (   is_ext_list
  3970.               || is_ext_range
  3971.               || is_ext_year))
  3972.        {
  3973.          is_ext_list=is_ext_range=is_ext_year = FALSE;
  3974.          *month_list.month = act_month;
  3975.          *month_list.year = act_year;
  3976.        }
  3977.     }
  3978. }
  3979.  
  3980.  
  3981.  
  3982. #ifdef ANSI_PROTO
  3983. LOCAL void
  3984. eliminate_invalid_data (void)
  3985. #else /* !ANSI_PROTO */
  3986.    LOCAL void
  3987. eliminate_invalid_data ()
  3988. #endif /* !ANSI_PROTO */
  3989. /*
  3990.    Eliminates invalid command line argument values
  3991.      and sets some internal variables according to command line arguments
  3992. */
  3993. {
  3994.    /*
  3995.       Correct month and year
  3996.    */
  3997.    if (   !month
  3998.        && !year)
  3999.     {
  4000.       month = act_month;
  4001.       year = act_year;
  4002.     }
  4003.    else
  4004.      if (   year < YEAR_MIN
  4005.          || year > YEAR_MAX)
  4006.       {
  4007.         if (   month
  4008.             && year)
  4009.           month = act_month;
  4010.         year = act_year;
  4011.       }
  4012.    if (   year_flag
  4013.        && month)
  4014.      month = 0;
  4015.    if (   month
  4016.        && !*month_list.month)
  4017.      *month_list.month = month;
  4018.    if (   year
  4019.        && !*month_list.year)
  4020.      *month_list.year = year;
  4021.    /*
  4022.       Set default amount of month rows and columns according to calendar format
  4023.    */
  4024.    if (   is_3month_mode
  4025.        || is_3month_mode2)
  4026.     {
  4027.       /*
  4028.          Set fixed amount of month rows and columns for 3 month mode
  4029.            (-b<> flag is ignored)
  4030.       */
  4031.       if (special_calsheet_flag)
  4032.        {
  4033.          if (cal_julian_flag)
  4034.           {
  4035.             out_rows = JI3_OUT_ROWS;
  4036.             out_cols = JI3_OUT_COLS;
  4037.           }
  4038.          else
  4039.            if (cal_both_dates_flag)
  4040.             {
  4041.               out_rows = BI3_OUT_ROWS;
  4042.               out_cols = BI3_OUT_COLS;
  4043.             }
  4044.            else
  4045.             {
  4046.               out_rows = SI3_OUT_ROWS;
  4047.               out_cols = SI3_OUT_COLS;
  4048.             }
  4049.        }
  4050.       else
  4051.        {
  4052.          if (cal_julian_flag)
  4053.           {
  4054.             out_rows = J3_OUT_ROWS;
  4055.             out_cols = J3_OUT_COLS;
  4056.           }
  4057.          else
  4058.            if (cal_both_dates_flag)
  4059.             {
  4060.               out_rows = B3_OUT_ROWS;
  4061.               out_cols = B3_OUT_COLS;
  4062.             }
  4063.            else
  4064.             {
  4065.               out_rows = S3_OUT_ROWS;
  4066.               out_cols = S3_OUT_COLS;
  4067.             }
  4068.        }
  4069.     }
  4070.    else
  4071.     {
  4072.       /*
  4073.          Set default amount of month columns according to calendar format
  4074.       */
  4075.       if (special_calsheet_flag)
  4076.        {
  4077.          if (cal_julian_flag)
  4078.            out_cols = JI_OUT_COLS;
  4079.          else
  4080.            if (cal_both_dates_flag)
  4081.              out_cols = BI_OUT_COLS;
  4082.            else
  4083.              out_cols = SI_OUT_COLS;
  4084.        }
  4085.       else
  4086.        {
  4087.          if (cal_julian_flag)
  4088.            out_cols = J_OUT_COLS;
  4089.          else
  4090.            if (cal_both_dates_flag)
  4091.              out_cols = B_OUT_COLS;
  4092.            else
  4093.              out_cols = S_OUT_COLS;
  4094.        }
  4095.       /*
  4096.          Set amount of month cols according to calendar format
  4097.       */
  4098.       switch (out_rows)
  4099.        {
  4100.          case 1:
  4101.            out_cols = MONTH_MAX;
  4102.            break;
  4103.          case 2:
  4104.            out_cols = 6;
  4105.            break;
  4106.          case 3:
  4107.            out_cols = 4;
  4108.            break;
  4109.          case 4:
  4110.            out_cols = 3;
  4111.            break;
  4112.          case 6:
  4113.            out_cols = 2;
  4114.            break;
  4115.          case 12:
  4116.            out_cols = MONTH_MIN;
  4117.            break;
  4118.          default:
  4119.            /*
  4120.               Set default amounts of month rows according to calendar format
  4121.            */
  4122.            if (special_calsheet_flag)
  4123.             {
  4124.               if (cal_julian_flag)
  4125.                 out_rows = JI_OUT_ROWS;
  4126.               else
  4127.                 if (cal_both_dates_flag)
  4128.                   out_rows = BI_OUT_ROWS;
  4129.                 else
  4130.                   out_rows = SI_OUT_ROWS;
  4131.             }
  4132.            else
  4133.             {
  4134.               if (cal_julian_flag)
  4135.                 out_rows = J_OUT_ROWS;
  4136.               else
  4137.                 if (cal_both_dates_flag)
  4138.                   out_rows = B_OUT_ROWS;
  4139.                 else
  4140.                   out_rows = S_OUT_ROWS;
  4141.             }
  4142.        }
  4143.     }
  4144.    /*
  4145.       Set the single day format length according to mode
  4146.    */
  4147.    if (cal_julian_flag)
  4148.      fmt_len = 4;
  4149.    else
  4150.      if (cal_both_dates_flag)
  4151.        fmt_len = 8;
  4152.      else
  4153.        fmt_len = 3;
  4154.    /*
  4155.       Set starting day of week if not set by command line argument
  4156.         (special value -1 found)
  4157.    */
  4158.    if (start_day < 0)
  4159.      start_day = weekday_of_date (act_day, act_month, act_year);
  4160.    else
  4161.      if (!start_day)
  4162. #if USE_GER
  4163.        start_day = DAY_MIN;
  4164. #else /* !USE_GER */
  4165.        start_day = DAY_MAX;
  4166. #endif /* !USE_GER */
  4167. }
  4168.